From e9694e72184abe232c6d9685f41c2bba475f52f0 Mon Sep 17 00:00:00 2001 From: skullydazed Date: Tue, 10 Nov 2020 15:02:44 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20master=20@?= =?UTF-8?q?=20aae3b35c0fc363e4a9246e774b714a7a1ef7b6c0=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nojekyll | 0 CNAME | 1 + ChangeLog/20190830.md | 53 ++ ChangeLog/20200229.md | 75 ++ ChangeLog/20200530.md | 239 +++++ ChangeLog/20200829.md | 148 +++ README.md | 43 + _langs.md | 9 + _summary.md | 180 ++++ adc_driver.md | 150 +++ api_development_environment.md | 3 + api_development_overview.md | 44 + api_docs.md | 68 ++ api_overview.md | 15 + arm_debugging.md | 87 ++ breaking_changes.md | 110 +++ breaking_changes_instructions.md | 42 + cli.md | 38 + cli_commands.md | 339 +++++++ cli_configuration.md | 121 +++ cli_development.md | 219 +++++ coding_conventions_c.md | 58 ++ coding_conventions_python.md | 326 +++++++ compatible_microcontrollers.md | 37 + config_options.md | 414 +++++++++ configurator_default_keymaps.md | 193 ++++ configurator_step_by_step.md | 58 ++ configurator_troubleshooting.md | 26 + contributing.md | 168 ++++ custom_matrix.md | 108 +++ custom_quantum_functions.md | 391 ++++++++ de/README.md | 33 + de/_summary.md | 122 +++ de/cli.md | 169 ++++ de/driver_installation_zadig.md | 47 + de/newbs.md | 22 + de/newbs_building_firmware.md | 78 ++ de/newbs_flashing.md | 369 ++++++++ de/newbs_getting_started.md | 101 ++ de/newbs_learn_more_resources.md | 14 + de/newbs_testing_debugging.md | 100 ++ documentation_best_practices.md | 64 ++ documentation_templates.md | 40 + driver_installation_zadig.md | 48 + eeprom_driver.md | 71 ++ es/README.md | 32 + es/_summary.md | 122 +++ es/hardware.md | 8 + es/hardware_avr.md | 180 ++++ es/hardware_drivers.md | 36 + es/hardware_keyboard_guidelines.md | 149 +++ es/newbs.md | 23 + es/newbs_best_practices.md | 159 ++++ es/newbs_building_firmware.md | 81 ++ es/newbs_building_firmware_configurator.md | 105 +++ es/newbs_flashing.md | 351 +++++++ es/newbs_getting_started.md | 103 +++ es/newbs_learn_more_resources.md | 15 + es/newbs_testing_debugging.md | 99 ++ faq_build.md | 69 ++ faq_debug.md | 148 +++ faq_general.md | 53 ++ faq_keymap.md | 156 ++++ feature_advanced_keycodes.md | 44 + feature_audio.md | 323 +++++++ feature_auto_shift.md | 167 ++++ feature_backlight.md | 217 +++++ feature_bluetooth.md | 45 + feature_bootmagic.md | 177 ++++ feature_combo.md | 103 +++ feature_command.md | 51 ++ feature_debounce_type.md | 151 +++ feature_dip_switch.md | 104 +++ feature_dynamic_macros.md | 66 ++ feature_encoders.md | 76 ++ feature_grave_esc.md | 32 + feature_haptic_feedback.md | 158 ++++ feature_hd44780.md | 57 ++ feature_joystick.md | 147 +++ feature_key_lock.md | 22 + feature_layers.md | 93 ++ feature_layouts.md | 109 +++ feature_leader_key.md | 146 +++ feature_led_indicators.md | 116 +++ feature_led_matrix.md | 90 ++ feature_macros.md | 397 ++++++++ feature_mouse_keys.md | 142 +++ feature_oled_driver.md | 377 ++++++++ feature_pointing_device.md | 49 + feature_ps2_mouse.md | 306 +++++++ feature_rawhid.md | 69 ++ feature_rgb_matrix.md | 510 +++++++++++ feature_rgblight.md | 520 +++++++++++ feature_space_cadet.md | 60 ++ feature_split_keyboard.md | 246 +++++ feature_stenography.md | 132 +++ feature_swap_hands.md | 31 + feature_tap_dance.md | 512 +++++++++++ feature_terminal.md | 107 +++ feature_thermal_printer.md | 10 + feature_unicode.md | 272 ++++++ feature_userspace.md | 255 ++++++ feature_velocikey.md | 30 + feature_wpm.md | 25 + flashing.md | 242 +++++ flashing_bootloadhid.md | 70 ++ fr-fr/ChangeLog/20190830.md | 52 ++ fr-fr/README.md | 32 + fr-fr/_summary.md | 126 +++ fr-fr/breaking_changes.md | 107 +++ fr-fr/cli.md | 146 +++ fr-fr/cli_configuration.md | 121 +++ fr-fr/contributing.md | 154 ++++ fr-fr/driver_installation_zadig.md | 46 + fr-fr/faq.md | 6 + fr-fr/faq_build.md | 154 ++++ fr-fr/faq_debug.md | 157 ++++ fr-fr/faq_general.md | 16 + fr-fr/faq_keymap.md | 161 ++++ fr-fr/flashing.md | 238 +++++ fr-fr/getting_started_getting_help.md | 15 + fr-fr/getting_started_github.md | 67 ++ fr-fr/getting_started_introduction.md | 62 ++ fr-fr/newbs.md | 23 + fr-fr/newbs_best_practices.md | 161 ++++ fr-fr/newbs_building_firmware.md | 81 ++ fr-fr/newbs_building_firmware_configurator.md | 105 +++ fr-fr/newbs_flashing.md | 367 ++++++++ fr-fr/newbs_getting_started.md | 101 ++ fr-fr/newbs_learn_more_resources.md | 14 + fr-fr/newbs_testing_debugging.md | 102 +++ fuse.txt | 50 + getting_started_docker.md | 47 + getting_started_github.md | 65 ++ getting_started_introduction.md | 60 ++ getting_started_make_guide.md | 144 +++ getting_started_vagrant.md | 56 ++ gitbook/images/color-wheel.svg | 441 +++++++++ gitbook/images/favicon.ico | Bin 0 -> 1150 bytes gitbook/images/favicon.png | Bin 0 -> 793 bytes hand_wire.md | 244 +++++ hardware_avr.md | 180 ++++ hardware_drivers.md | 39 + hardware_keyboard_guidelines.md | 234 +++++ he-il/README.md | 34 + he-il/_summary.md | 140 +++ he-il/documentation_best_practices.md | 67 ++ he-il/faq.md | 8 + he-il/faq_general.md | 17 + he-il/getting_started_getting_help.md | 17 + he-il/getting_started_github.md | 75 ++ he-il/getting_started_introduction.md | 72 ++ he-il/hardware.md | 10 + he-il/newbs_learn_more_resources.md | 16 + he-il/proton_c_conversion.md | 36 + he-il/quantum_keycodes.md | 25 + how_a_matrix_works.md | 99 ++ how_keyboards_work.md | 76 ++ i2c_driver.md | 133 +++ index.html | 166 ++++ internals_SERIAL_USB.md | 314 +++++++ internals_asfdoc_sam0_usb_group.md | 25 + internals_defines.md | 78 ++ internals_gpio_control.md | 23 + internals_group_sam0_utils.md | 571 ++++++++++++ internals_group_sam0_utils_status_codes.md | 92 ++ internals_input_callback_reg.md | 169 ++++ internals_midi_device.md | 143 +++ internals_midi_device_setup_process.md | 31 + internals_midi_util.md | 54 ++ internals_pfleury_lcd.md | 27 + internals_send_functions.md | 241 +++++ internals_sysex_tools.md | 61 ++ internals_udc_desc_group.md | 79 ++ internals_udc_group.md | 148 +++ internals_udc_group_interne.md | 267 ++++++ internals_udd_group.md | 171 ++++ internals_udi_group.md | 75 ++ internals_udi_hid_group.md | 28 + internals_udi_hid_group_internal.md | 34 + ...nals_udi_hid_keyboard_group_single_desc.md | 11 + internals_usb_atmel_ids_group.md | 9 + internals_usb_device_group.md | 27 + internals_usb_device_udd_group.md | 325 +++++++ internals_usb_group.md | 9 + internals_usb_hid_protocol.md | 118 +++ internals_usb_protocol_group.md | 806 ++++++++++++++++ isp_flashing_guide.md | 253 +++++ ja/README.md | 48 + ja/_summary.md | 177 ++++ ja/api_development_environment.md | 8 + ja/api_development_overview.md | 49 + ja/api_docs.md | 73 ++ ja/api_overview.md | 20 + ja/arm_debugging.md | 92 ++ ja/breaking_changes.md | 121 +++ ja/breaking_changes_instructions.md | 51 ++ ja/cli.md | 43 + ja/cli_commands.md | 296 ++++++ ja/cli_configuration.md | 126 +++ ja/cli_development.md | 223 +++++ ja/coding_conventions_c.md | 63 ++ ja/coding_conventions_python.md | 331 +++++++ ja/compatible_microcontrollers.md | 42 + ja/config_options.md | 409 +++++++++ ja/configurator_step_by_step.md | 67 ++ ja/configurator_troubleshooting.md | 32 + ja/contributing.md | 173 ++++ ja/custom_matrix.md | 114 +++ ja/custom_quantum_functions.md | 495 ++++++++++ ja/documentation_best_practices.md | 69 ++ ja/documentation_templates.md | 45 + ja/driver_installation_zadig.md | 53 ++ ja/faq_build.md | 137 +++ ja/faq_debug.md | 140 +++ ja/faq_general.md | 58 ++ ja/faq_keymap.md | 160 ++++ ja/feature_advanced_keycodes.md | 46 + ja/feature_audio.md | 328 +++++++ ja/feature_auto_shift.md | 135 +++ ja/feature_backlight.md | 222 +++++ ja/feature_bluetooth.md | 49 + ja/feature_bootmagic.md | 182 ++++ ja/feature_combo.md | 108 +++ ja/feature_command.md | 56 ++ ja/feature_debounce_type.md | 47 + ja/feature_dip_switch.md | 109 +++ ja/feature_dynamic_macros.md | 71 ++ ja/feature_encoders.md | 81 ++ ja/feature_grave_esc.md | 37 + ja/feature_haptic_feedback.md | 163 ++++ ja/feature_hd44780.md | 62 ++ ja/feature_key_lock.md | 27 + ja/feature_layers.md | 99 ++ ja/feature_layouts.md | 114 +++ ja/feature_leader_key.md | 151 +++ ja/feature_led_matrix.md | 95 ++ ja/feature_macros.md | 402 ++++++++ ja/feature_mouse_keys.md | 144 +++ ja/feature_pointing_device.md | 54 ++ ja/feature_ps2_mouse.md | 303 ++++++ ja/feature_split_keyboard.md | 251 +++++ ja/feature_stenography.md | 136 +++ ja/feature_swap_hands.md | 36 + ja/feature_tap_dance.md | 527 +++++++++++ ja/feature_terminal.md | 112 +++ ja/feature_thermal_printer.md | 15 + ja/feature_userspace.md | 260 ++++++ ja/feature_velocikey.md | 35 + ja/feature_wpm.md | 24 + ja/flashing.md | 247 +++++ ja/flashing_bootloadhid.md | 75 ++ ja/getting_started_docker.md | 52 ++ ja/getting_started_github.md | 70 ++ ja/getting_started_introduction.md | 65 ++ ja/getting_started_make_guide.md | 149 +++ ja/getting_started_vagrant.md | 61 ++ ja/hardware_avr.md | 188 ++++ ja/hardware_drivers.md | 45 + ja/hardware_keyboard_guidelines.md | 222 +++++ ja/how_a_matrix_works.md | 104 +++ ja/how_keyboards_work.md | 74 ++ ja/i2c_driver.md | 138 +++ ja/internals_gpio_control.md | 28 + ja/internals_input_callback_reg.md | 174 ++++ ja/isp_flashing_guide.md | 284 ++++++ ja/keymap.md | 187 ++++ ja/mod_tap.md | 59 ++ ja/newbs.md | 48 + ja/newbs_building_firmware.md | 81 ++ ja/newbs_building_firmware_configurator.md | 20 + ja/newbs_flashing.md | 127 +++ ja/newbs_getting_started.md | 156 ++++ ja/newbs_git_best_practices.md | 24 + ja/newbs_git_resolving_merge_conflicts.md | 94 ++ ja/newbs_git_resynchronize_a_branch.md | 88 ++ ja/newbs_git_using_your_master_branch.md | 101 ++ ja/newbs_learn_more_resources.md | 45 + ja/newbs_testing_debugging.md | 104 +++ ja/one_shot_keys.md | 107 +++ ja/other_eclipse.md | 93 ++ ja/other_vscode.md | 122 +++ ja/pr_checklist.md | 134 +++ ja/proton_c_conversion.md | 97 ++ ja/quantum_keycodes.md | 20 + ja/ref_functions.md | 124 +++ ja/reference_configurator_support.md | 202 ++++ ja/reference_glossary.md | 173 ++++ ja/reference_info_json.md | 78 ++ ja/reference_keymap_extras.md | 88 ++ ja/serial_driver.md | 75 ++ ja/support.md | 22 + ja/syllabus.md | 75 ++ ja/tap_hold.md | 196 ++++ ja/translating.md | 60 ++ ja/understanding_qmk.md | 195 ++++ keycodes.md | 564 ++++++++++++ keycodes_basic.md | 256 ++++++ keycodes_us_ansi_shifted.md | 37 + keymap.md | 184 ++++ ko-kr/README.md | 33 + ko-kr/getting_started_build_tools.md | 156 ++++ ko-kr/getting_started_getting_help.md | 17 + ko-kr/getting_started_github.md | 67 ++ mod_tap.md | 61 ++ newbs.md | 30 + newbs_building_firmware.md | 64 ++ newbs_building_firmware_configurator.md | 13 + newbs_flashing.md | 111 +++ newbs_getting_started.md | 143 +++ newbs_git_best_practices.md | 16 + newbs_git_resolving_merge_conflicts.md | 79 ++ newbs_git_resynchronize_a_branch.md | 71 ++ newbs_git_using_your_master_branch.md | 74 ++ newbs_learn_more_resources.md | 17 + newbs_testing_debugging.md | 94 ++ one_shot_keys.md | 102 +++ other_eclipse.md | 88 ++ other_vscode.md | 117 +++ platformdev_chibios_earlyinit.md | 64 ++ platformdev_selecting_arm_mcu.md | 58 ++ power.txt | 62 ++ pr_checklist.md | 128 +++ proton_c_conversion.md | 90 ++ pt-br/README.md | 31 + pt-br/_summary.md | 122 +++ qmk.css | 862 ++++++++++++++++++ qmk_custom_dark.css | 29 + qmk_custom_light.css | 30 + quantum_keycodes.md | 15 + redirects.json | 52 ++ ref_functions.md | 119 +++ reference_configurator_support.md | 197 ++++ reference_glossary.md | 167 ++++ reference_info_json.md | 73 ++ reference_keymap_extras.md | 83 ++ ru-ru/README.md | 32 + ru-ru/_summary.md | 124 +++ ru-ru/getting_started_build_tools.md | 153 ++++ ru-ru/getting_started_getting_help.md | 15 + ru-ru/getting_started_github.md | 64 ++ ru-ru/getting_started_introduction.md | 58 ++ ru-ru/newbs.md | 23 + ru-ru/newbs_getting_started.md | 102 +++ serial_driver.md | 69 ++ spi_driver.md | 138 +++ support.md | 17 + sw.js | 83 ++ syllabus.md | 70 ++ tap_hold.md | 190 ++++ translating.md | 55 ++ understanding_qmk.md | 191 ++++ unit_testing.md | 68 ++ usb_nkro.txt | 160 ++++ ws2812_driver.md | 122 +++ zh-cn/README.md | 32 + zh-cn/_summary.md | 133 +++ zh-cn/contributing.md | 205 +++++ zh-cn/custom_quantum_functions.md | 490 ++++++++++ zh-cn/faq.md | 6 + zh-cn/faq_build.md | 122 +++ zh-cn/faq_debug.md | 141 +++ zh-cn/faq_general.md | 19 + zh-cn/faq_keymap.md | 151 +++ zh-cn/getting_started_getting_help.md | 15 + zh-cn/getting_started_github.md | 65 ++ zh-cn/getting_started_introduction.md | 54 ++ zh-cn/newbs.md | 23 + zh-cn/newbs_best_practices.md | 163 ++++ zh-cn/newbs_building_firmware.md | 81 ++ zh-cn/newbs_flashing.md | 307 +++++++ zh-cn/newbs_getting_started.md | 102 +++ zh-cn/newbs_learn_more_resources.md | 15 + zh-cn/newbs_testing_debugging.md | 44 + zh-cn/reference_glossary.md | 167 ++++ 375 files changed, 44952 insertions(+) create mode 100644 .nojekyll create mode 100644 CNAME create mode 100644 ChangeLog/20190830.md create mode 100644 ChangeLog/20200229.md create mode 100644 ChangeLog/20200530.md create mode 100644 ChangeLog/20200829.md create mode 100644 README.md create mode 100644 _langs.md create mode 100644 _summary.md create mode 100644 adc_driver.md create mode 100644 api_development_environment.md create mode 100644 api_development_overview.md create mode 100644 api_docs.md create mode 100644 api_overview.md create mode 100644 arm_debugging.md create mode 100644 breaking_changes.md create mode 100644 breaking_changes_instructions.md create mode 100644 cli.md create mode 100644 cli_commands.md create mode 100644 cli_configuration.md create mode 100644 cli_development.md create mode 100644 coding_conventions_c.md create mode 100644 coding_conventions_python.md create mode 100644 compatible_microcontrollers.md create mode 100644 config_options.md create mode 100644 configurator_default_keymaps.md create mode 100644 configurator_step_by_step.md create mode 100644 configurator_troubleshooting.md create mode 100644 contributing.md create mode 100644 custom_matrix.md create mode 100644 custom_quantum_functions.md create mode 100644 de/README.md create mode 100644 de/_summary.md create mode 100644 de/cli.md create mode 100644 de/driver_installation_zadig.md create mode 100644 de/newbs.md create mode 100644 de/newbs_building_firmware.md create mode 100644 de/newbs_flashing.md create mode 100644 de/newbs_getting_started.md create mode 100644 de/newbs_learn_more_resources.md create mode 100644 de/newbs_testing_debugging.md create mode 100644 documentation_best_practices.md create mode 100644 documentation_templates.md create mode 100644 driver_installation_zadig.md create mode 100644 eeprom_driver.md create mode 100644 es/README.md create mode 100644 es/_summary.md create mode 100644 es/hardware.md create mode 100644 es/hardware_avr.md create mode 100644 es/hardware_drivers.md create mode 100644 es/hardware_keyboard_guidelines.md create mode 100644 es/newbs.md create mode 100644 es/newbs_best_practices.md create mode 100644 es/newbs_building_firmware.md create mode 100644 es/newbs_building_firmware_configurator.md create mode 100644 es/newbs_flashing.md create mode 100644 es/newbs_getting_started.md create mode 100644 es/newbs_learn_more_resources.md create mode 100644 es/newbs_testing_debugging.md create mode 100644 faq_build.md create mode 100644 faq_debug.md create mode 100644 faq_general.md create mode 100644 faq_keymap.md create mode 100644 feature_advanced_keycodes.md create mode 100644 feature_audio.md create mode 100644 feature_auto_shift.md create mode 100644 feature_backlight.md create mode 100644 feature_bluetooth.md create mode 100644 feature_bootmagic.md create mode 100644 feature_combo.md create mode 100644 feature_command.md create mode 100644 feature_debounce_type.md create mode 100644 feature_dip_switch.md create mode 100644 feature_dynamic_macros.md create mode 100644 feature_encoders.md create mode 100644 feature_grave_esc.md create mode 100644 feature_haptic_feedback.md create mode 100644 feature_hd44780.md create mode 100644 feature_joystick.md create mode 100644 feature_key_lock.md create mode 100644 feature_layers.md create mode 100644 feature_layouts.md create mode 100644 feature_leader_key.md create mode 100644 feature_led_indicators.md create mode 100644 feature_led_matrix.md create mode 100644 feature_macros.md create mode 100644 feature_mouse_keys.md create mode 100644 feature_oled_driver.md create mode 100644 feature_pointing_device.md create mode 100644 feature_ps2_mouse.md create mode 100644 feature_rawhid.md create mode 100644 feature_rgb_matrix.md create mode 100644 feature_rgblight.md create mode 100644 feature_space_cadet.md create mode 100644 feature_split_keyboard.md create mode 100644 feature_stenography.md create mode 100644 feature_swap_hands.md create mode 100644 feature_tap_dance.md create mode 100644 feature_terminal.md create mode 100644 feature_thermal_printer.md create mode 100644 feature_unicode.md create mode 100644 feature_userspace.md create mode 100644 feature_velocikey.md create mode 100644 feature_wpm.md create mode 100644 flashing.md create mode 100644 flashing_bootloadhid.md create mode 100644 fr-fr/ChangeLog/20190830.md create mode 100644 fr-fr/README.md create mode 100644 fr-fr/_summary.md create mode 100644 fr-fr/breaking_changes.md create mode 100644 fr-fr/cli.md create mode 100644 fr-fr/cli_configuration.md create mode 100644 fr-fr/contributing.md create mode 100644 fr-fr/driver_installation_zadig.md create mode 100644 fr-fr/faq.md create mode 100644 fr-fr/faq_build.md create mode 100644 fr-fr/faq_debug.md create mode 100644 fr-fr/faq_general.md create mode 100644 fr-fr/faq_keymap.md create mode 100644 fr-fr/flashing.md create mode 100644 fr-fr/getting_started_getting_help.md create mode 100644 fr-fr/getting_started_github.md create mode 100644 fr-fr/getting_started_introduction.md create mode 100644 fr-fr/newbs.md create mode 100644 fr-fr/newbs_best_practices.md create mode 100644 fr-fr/newbs_building_firmware.md create mode 100644 fr-fr/newbs_building_firmware_configurator.md create mode 100644 fr-fr/newbs_flashing.md create mode 100644 fr-fr/newbs_getting_started.md create mode 100644 fr-fr/newbs_learn_more_resources.md create mode 100644 fr-fr/newbs_testing_debugging.md create mode 100644 fuse.txt create mode 100644 getting_started_docker.md create mode 100644 getting_started_github.md create mode 100644 getting_started_introduction.md create mode 100644 getting_started_make_guide.md create mode 100644 getting_started_vagrant.md create mode 100644 gitbook/images/color-wheel.svg create mode 100644 gitbook/images/favicon.ico create mode 100644 gitbook/images/favicon.png create mode 100644 hand_wire.md create mode 100644 hardware_avr.md create mode 100644 hardware_drivers.md create mode 100644 hardware_keyboard_guidelines.md create mode 100644 he-il/README.md create mode 100644 he-il/_summary.md create mode 100644 he-il/documentation_best_practices.md create mode 100644 he-il/faq.md create mode 100644 he-il/faq_general.md create mode 100644 he-il/getting_started_getting_help.md create mode 100644 he-il/getting_started_github.md create mode 100644 he-il/getting_started_introduction.md create mode 100644 he-il/hardware.md create mode 100644 he-il/newbs_learn_more_resources.md create mode 100644 he-il/proton_c_conversion.md create mode 100644 he-il/quantum_keycodes.md create mode 100644 how_a_matrix_works.md create mode 100644 how_keyboards_work.md create mode 100644 i2c_driver.md create mode 100644 index.html create mode 100644 internals_SERIAL_USB.md create mode 100644 internals_asfdoc_sam0_usb_group.md create mode 100644 internals_defines.md create mode 100644 internals_gpio_control.md create mode 100644 internals_group_sam0_utils.md create mode 100644 internals_group_sam0_utils_status_codes.md create mode 100644 internals_input_callback_reg.md create mode 100644 internals_midi_device.md create mode 100644 internals_midi_device_setup_process.md create mode 100644 internals_midi_util.md create mode 100644 internals_pfleury_lcd.md create mode 100644 internals_send_functions.md create mode 100644 internals_sysex_tools.md create mode 100644 internals_udc_desc_group.md create mode 100644 internals_udc_group.md create mode 100644 internals_udc_group_interne.md create mode 100644 internals_udd_group.md create mode 100644 internals_udi_group.md create mode 100644 internals_udi_hid_group.md create mode 100644 internals_udi_hid_group_internal.md create mode 100644 internals_udi_hid_keyboard_group_single_desc.md create mode 100644 internals_usb_atmel_ids_group.md create mode 100644 internals_usb_device_group.md create mode 100644 internals_usb_device_udd_group.md create mode 100644 internals_usb_group.md create mode 100644 internals_usb_hid_protocol.md create mode 100644 internals_usb_protocol_group.md create mode 100644 isp_flashing_guide.md create mode 100644 ja/README.md create mode 100644 ja/_summary.md create mode 100644 ja/api_development_environment.md create mode 100644 ja/api_development_overview.md create mode 100644 ja/api_docs.md create mode 100644 ja/api_overview.md create mode 100644 ja/arm_debugging.md create mode 100644 ja/breaking_changes.md create mode 100644 ja/breaking_changes_instructions.md create mode 100644 ja/cli.md create mode 100644 ja/cli_commands.md create mode 100644 ja/cli_configuration.md create mode 100644 ja/cli_development.md create mode 100644 ja/coding_conventions_c.md create mode 100644 ja/coding_conventions_python.md create mode 100644 ja/compatible_microcontrollers.md create mode 100644 ja/config_options.md create mode 100644 ja/configurator_step_by_step.md create mode 100644 ja/configurator_troubleshooting.md create mode 100644 ja/contributing.md create mode 100644 ja/custom_matrix.md create mode 100644 ja/custom_quantum_functions.md create mode 100644 ja/documentation_best_practices.md create mode 100644 ja/documentation_templates.md create mode 100644 ja/driver_installation_zadig.md create mode 100644 ja/faq_build.md create mode 100644 ja/faq_debug.md create mode 100644 ja/faq_general.md create mode 100644 ja/faq_keymap.md create mode 100644 ja/feature_advanced_keycodes.md create mode 100644 ja/feature_audio.md create mode 100644 ja/feature_auto_shift.md create mode 100644 ja/feature_backlight.md create mode 100644 ja/feature_bluetooth.md create mode 100644 ja/feature_bootmagic.md create mode 100644 ja/feature_combo.md create mode 100644 ja/feature_command.md create mode 100644 ja/feature_debounce_type.md create mode 100644 ja/feature_dip_switch.md create mode 100644 ja/feature_dynamic_macros.md create mode 100644 ja/feature_encoders.md create mode 100644 ja/feature_grave_esc.md create mode 100644 ja/feature_haptic_feedback.md create mode 100644 ja/feature_hd44780.md create mode 100644 ja/feature_key_lock.md create mode 100644 ja/feature_layers.md create mode 100644 ja/feature_layouts.md create mode 100644 ja/feature_leader_key.md create mode 100644 ja/feature_led_matrix.md create mode 100644 ja/feature_macros.md create mode 100644 ja/feature_mouse_keys.md create mode 100644 ja/feature_pointing_device.md create mode 100644 ja/feature_ps2_mouse.md create mode 100644 ja/feature_split_keyboard.md create mode 100644 ja/feature_stenography.md create mode 100644 ja/feature_swap_hands.md create mode 100644 ja/feature_tap_dance.md create mode 100644 ja/feature_terminal.md create mode 100644 ja/feature_thermal_printer.md create mode 100644 ja/feature_userspace.md create mode 100644 ja/feature_velocikey.md create mode 100644 ja/feature_wpm.md create mode 100644 ja/flashing.md create mode 100644 ja/flashing_bootloadhid.md create mode 100644 ja/getting_started_docker.md create mode 100644 ja/getting_started_github.md create mode 100644 ja/getting_started_introduction.md create mode 100644 ja/getting_started_make_guide.md create mode 100644 ja/getting_started_vagrant.md create mode 100644 ja/hardware_avr.md create mode 100644 ja/hardware_drivers.md create mode 100644 ja/hardware_keyboard_guidelines.md create mode 100644 ja/how_a_matrix_works.md create mode 100644 ja/how_keyboards_work.md create mode 100644 ja/i2c_driver.md create mode 100644 ja/internals_gpio_control.md create mode 100644 ja/internals_input_callback_reg.md create mode 100644 ja/isp_flashing_guide.md create mode 100644 ja/keymap.md create mode 100644 ja/mod_tap.md create mode 100644 ja/newbs.md create mode 100644 ja/newbs_building_firmware.md create mode 100644 ja/newbs_building_firmware_configurator.md create mode 100644 ja/newbs_flashing.md create mode 100644 ja/newbs_getting_started.md create mode 100644 ja/newbs_git_best_practices.md create mode 100644 ja/newbs_git_resolving_merge_conflicts.md create mode 100644 ja/newbs_git_resynchronize_a_branch.md create mode 100644 ja/newbs_git_using_your_master_branch.md create mode 100644 ja/newbs_learn_more_resources.md create mode 100644 ja/newbs_testing_debugging.md create mode 100644 ja/one_shot_keys.md create mode 100644 ja/other_eclipse.md create mode 100644 ja/other_vscode.md create mode 100644 ja/pr_checklist.md create mode 100644 ja/proton_c_conversion.md create mode 100644 ja/quantum_keycodes.md create mode 100644 ja/ref_functions.md create mode 100644 ja/reference_configurator_support.md create mode 100644 ja/reference_glossary.md create mode 100644 ja/reference_info_json.md create mode 100644 ja/reference_keymap_extras.md create mode 100644 ja/serial_driver.md create mode 100644 ja/support.md create mode 100644 ja/syllabus.md create mode 100644 ja/tap_hold.md create mode 100644 ja/translating.md create mode 100644 ja/understanding_qmk.md create mode 100644 keycodes.md create mode 100644 keycodes_basic.md create mode 100644 keycodes_us_ansi_shifted.md create mode 100644 keymap.md create mode 100644 ko-kr/README.md create mode 100644 ko-kr/getting_started_build_tools.md create mode 100644 ko-kr/getting_started_getting_help.md create mode 100644 ko-kr/getting_started_github.md create mode 100644 mod_tap.md create mode 100644 newbs.md create mode 100644 newbs_building_firmware.md create mode 100644 newbs_building_firmware_configurator.md create mode 100644 newbs_flashing.md create mode 100644 newbs_getting_started.md create mode 100644 newbs_git_best_practices.md create mode 100644 newbs_git_resolving_merge_conflicts.md create mode 100644 newbs_git_resynchronize_a_branch.md create mode 100644 newbs_git_using_your_master_branch.md create mode 100644 newbs_learn_more_resources.md create mode 100644 newbs_testing_debugging.md create mode 100644 one_shot_keys.md create mode 100644 other_eclipse.md create mode 100644 other_vscode.md create mode 100644 platformdev_chibios_earlyinit.md create mode 100644 platformdev_selecting_arm_mcu.md create mode 100644 power.txt create mode 100644 pr_checklist.md create mode 100644 proton_c_conversion.md create mode 100644 pt-br/README.md create mode 100644 pt-br/_summary.md create mode 100644 qmk.css create mode 100644 qmk_custom_dark.css create mode 100644 qmk_custom_light.css create mode 100644 quantum_keycodes.md create mode 100644 redirects.json create mode 100644 ref_functions.md create mode 100644 reference_configurator_support.md create mode 100644 reference_glossary.md create mode 100644 reference_info_json.md create mode 100644 reference_keymap_extras.md create mode 100644 ru-ru/README.md create mode 100644 ru-ru/_summary.md create mode 100644 ru-ru/getting_started_build_tools.md create mode 100644 ru-ru/getting_started_getting_help.md create mode 100644 ru-ru/getting_started_github.md create mode 100644 ru-ru/getting_started_introduction.md create mode 100644 ru-ru/newbs.md create mode 100644 ru-ru/newbs_getting_started.md create mode 100644 serial_driver.md create mode 100644 spi_driver.md create mode 100644 support.md create mode 100644 sw.js create mode 100644 syllabus.md create mode 100644 tap_hold.md create mode 100644 translating.md create mode 100644 understanding_qmk.md create mode 100644 unit_testing.md create mode 100644 usb_nkro.txt create mode 100644 ws2812_driver.md create mode 100644 zh-cn/README.md create mode 100644 zh-cn/_summary.md create mode 100644 zh-cn/contributing.md create mode 100644 zh-cn/custom_quantum_functions.md create mode 100644 zh-cn/faq.md create mode 100644 zh-cn/faq_build.md create mode 100644 zh-cn/faq_debug.md create mode 100644 zh-cn/faq_general.md create mode 100644 zh-cn/faq_keymap.md create mode 100644 zh-cn/getting_started_getting_help.md create mode 100644 zh-cn/getting_started_github.md create mode 100644 zh-cn/getting_started_introduction.md create mode 100644 zh-cn/newbs.md create mode 100644 zh-cn/newbs_best_practices.md create mode 100644 zh-cn/newbs_building_firmware.md create mode 100644 zh-cn/newbs_flashing.md create mode 100644 zh-cn/newbs_getting_started.md create mode 100644 zh-cn/newbs_learn_more_resources.md create mode 100644 zh-cn/newbs_testing_debugging.md create mode 100644 zh-cn/reference_glossary.md diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/CNAME b/CNAME new file mode 100644 index 00000000000..e089843e0bc --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.qmk.fm \ No newline at end of file diff --git a/ChangeLog/20190830.md b/ChangeLog/20190830.md new file mode 100644 index 00000000000..bd2d5e19c34 --- /dev/null +++ b/ChangeLog/20190830.md @@ -0,0 +1,53 @@ +# QMK Breaking Change - 2019 Aug 30 + +Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. + +This document marks the inaugural Breaking Change merge. A list of changes follows. + +## Core code formatting with clang-format + +* All core files (`drivers/`, `quantum/`, `tests/`, and `tmk_core/`) have been formatted with clang-format +* A travis process to reformat PR's on merge has been instituted +* You can use the new CLI command `qmk cformat` to format before submitting your PR if you wish. + +## LUFA USB descriptor cleanup + +* Some code cleanups related to the USB HID descriptors on AVR keyboards, to make them easier to read and understand +* More information: see https://github.com/qmk/qmk_firmware/pull/4871 +* No behaviour changes anticipated and no keymaps modified + +## Migrating `ACTION_LAYER_MOMENTARY()` entries in `fn_actions` to `MO()` keycodes + +* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` +* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity +* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features + +## Update Atreus to current code conventions + +* Duplicate include guards have bypassed the expected header processing behavior +* All keymaps affected are recommended to remove duplication of `/config.h` to `/keymaps//config.h` and only provide overrides at the keymap level + +## Backport changes to keymap language files from ZSA fork + +* Fixes an issue in the `keymap_br_abnt2.h` file that includes the wrong source (`keymap_common.h` instead of `keymap.h`) +* Updates the `keymap_swedish.h` file to be specific to swedish, and not just "nordic" in general. +* Any keymaps using this will need to remove `NO_*` and replace it with `SE_*`. + +## Update repo to use LUFA as a git submodule + +* `/lib/LUFA` removed from the repo +* LUFA set as a submodule, pointing to qmk/lufa +* This should allow more flexibility with LUFA, and allow us to keep the sub-module up to date, a lot more easily. It was ~2 years out of date with no easy path to fix that. This prevents that from being an issue in the future + +## Migrating `ACTION_BACKLIGHT_*()` entries in `fn_actions` to `BL_` keycodes + +* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` +* All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys +* If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features + +## Remove `KC_DELT` alias in favor of `KC_DEL` + +* `KC_DELT` was a redundant, undocumented alias for `KC_DELETE` +* It has been removed and all its uses replaced with the more common `KC_DEL` alias +* Around 90 keymaps (mostly for ErgoDox boards) have been modified as a result + diff --git a/ChangeLog/20200229.md b/ChangeLog/20200229.md new file mode 100644 index 00000000000..398fe01c0d0 --- /dev/null +++ b/ChangeLog/20200229.md @@ -0,0 +1,75 @@ +# QMK Breaking Change - 2020 Feb 29 Changelog + +Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. + + +## Update ChibiOS/ChibiOS-Contrib/uGFX submodules + +* General Notes + * A `make git-submodule` may be required after pulling the latest QMK firmware code to update affected submodules to the upgraded revisions + * Enabling link-time-optimization (`LINK_TIME_OPTIMIZATION_ENABLE = yes`) should work on a lot more boards +* Upgrade to ChibiOS ver19.1.3 + * This will allow QMK to update to upstream ChibiOS a lot easier -- the old version was ~2 years out of date. Automated update scripts have been made available to simplify future upgrades. + * Includes improved MCU support and bugfixes + * ChibiOS revision is now included in Command output + * Timers should now be more accurate +* Upgrade to newer ChibiOS-Contrib + * Also includes improved MCU support and bugfixes + * ChibiOS-Contrib revision is now included in Command output +* Upgrade to newer uGFX + * Required in order to support updated ChibiOS + + +## Fix ChibiOS timer overflow for 16-bit SysTick devices + +* On 16-bit SysTick devices, the timer subsystem in QMK was incorrectly dealing with overflow. + * When running at a 100000 SysTick frequency (possible on 16-bit devices, but uncommon), this overflow would occur after 0.65 seconds. +* Timers are now correctly handling this overflow case and timing should now be correct on ChibiOS/ARM. + + +## Update LUFA submodule + +* Updates the LUFA submodule to include updates from upstream (abcminiuser/lufa) +* Includes some cleanup for QMK DFU generation + + +## Encoder flip + +* Flips the encoder direction so that `clockwise == true` is for actually turning the knob clockwise +* Adds `ENCODER_DIRECTION_FLIP` define, so that reversing the expected dirction is simple for users. +* Cleans up documentation page for encoders + + +## Adding support for `BACKLIGHT_ON_STATE` for hardware PWM backlight + +* Previously, the define only affected software PWM, and hardware PWM always assumed an N-channel MOSFET. +* The hardware PWM backlight setup has been updated to respect this option. +* The default "on" state has been changed to `1` - **this impacts all keyboards using software PWM backlight that do not define it explicitly**. If your keyboard's backlight is acting strange, it may have a P-channel MOSFET, and will need to have `#define BACKLIGHT_ON_STATE 0` added to the keyboard-level `config.h`. Please see the PR for more detailed information. + + +## Migrating `ACTION_LAYER_TAP_KEY()` entries in `fn_actions` to `LT()` keycodes + +* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` +* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity +* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features + + +## Moving backlight keycode handling to `process_keycode/` + +* This refactors the backlight keycode logic to be clearer and more modular. +* All backlight-related keycodes are now actioned in a single file. +* The `ACTION_BACKLIGHT_*` macros have also been deleted. If you are still using these in a `fn_actions[]` block, please switch to using the backlight keycodes or functions directly. + + +## Refactor Planck keymaps to use Layout Macros + +* Refactor Planck keymaps to use layout macros instead of raw matrix assignments +* Makes keymaps revision-agnostic +* Should reduce noise and errors in Travis CI logs + + +## GON NerD codebase refactor + +* Splits the codebase for GON NerD 60 and NerdD TKL PCBs into two separate directories. +* If your keymap is for a NerD 60 PCB, your `make` command is now `make gon/nerd60:`. +* If your keymap is for a NerD TKL PCB, your `make` command is now `make gon/nerdtkl:`. diff --git a/ChangeLog/20200530.md b/ChangeLog/20200530.md new file mode 100644 index 00000000000..9def9ae1235 --- /dev/null +++ b/ChangeLog/20200530.md @@ -0,0 +1,239 @@ +# QMK Breaking Change - 2020 May 30 Changelog + +Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. + +The list of changes follows. + + +## Core Changes + +### Converting V-USB usbdrv to a submodule + +[#8321](https://github.com/qmk/qmk_firmware/pull/8321) and [qmk_compiler#62](https://github.com/qmk/qmk_compiler/pull/62). + +These PRs move the V-USB driver code out of the qmk_firmware repository and into a submodule pointed at https://github.com/obdev/v-usb. This will make it easier to update the codebase if needed, while applying any potential QMK-specific modifications by forking it to the QMK GitHub organization. + +### Unify Tap Hold functions and documentation + +[#8348](https://github.com/qmk/qmk_firmware/pull/8348) + +Updates all of the per key tap-hold functions to pass the `keyrecord_t` structure, and include documentation changes. + +Any remaining versions or code outside of the main repo will need to be converted: +| Old function | New Function | +|------------------------------------------------------|---------------------------------------------------------------------------| +|`uint16_t get_tapping_term(uint16_t keycode)` |`uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record)` | +|`bool get_ignore_mod_tap_interrupt(uint16_t keycode)` |`bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record)` | + +### Python Required In The Build Process + +[#9000](https://github.com/qmk/qmk_firmware/pull/9000) + +This is the last release of QMK that will work without having Python 3.6 (or later) installed. If your environment is not fully setup you will get a warning instructing you to set it up. + +After the next breaking change you will not be able to build if `bin/qmk hello` does not work. + +### Upgrade from tinyprintf to mpaland/printf + +[#8269](https://github.com/qmk/qmk_firmware/pull/8269) + +- Provides debug functionality on ChibiOS/ARM that is more compliant than previous integrations. +- Less maintenence, fewer QMK customisations, and allows QMK to sidestep previous compile and runtime issues. +- A `make git-submodule` may be required after pulling the latest QMK Firmware code to update to the new dependency. + +### Fixed RGB_DISABLE_AFTER_TIMEOUT to be seconds based & small internals cleanup + +[#6480](https://github.com/qmk/qmk_firmware/pull/6480) + +- Changes `RGB_DISABLE_AFTER_TIMEOUT` to be based on milliseconds instead of ticks. +- Includes a code cleanup, resulting in a savings of 100 bytes, depending on features used. +- Fixed issues with timeouts / suspending at the wrong time not turning off all LEDs in some cases. + +The `RGB_DISABLE_AFTER_TIMEOUT` definition is now deprecated, and has been superseded by `RGB_DISABLE_TIMEOUT`. To use the new definition, rename `RGB_DISABLE_AFTER_TIMEOUT` to `RGB_DISABLE_TIMEOUT` in your `config.h` file, and multiply the value set by 1200. + +Before: `#define RGB_DISABLE_AFTER_TIMEOUT 100` +After: `#define RGB_DISABLE_TIMEOUT 120000` + +### Switch to qmk forks for everything + +[#9019](https://github.com/qmk/qmk_firmware/pull/9019) + +Fork all QMK submodules to protect against upstream repositories disappearing. + +### code cleanup regarding deprecated macro PLAY_NOTE_ARRAY by replacing it with PLAY_SONG + +[#8484](https://github.com/qmk/qmk_firmware/pull/8484) + +Removes the deprecated `PLAY_NOTE_ARRAY` macro. References to it are replaced with `PLAY_SONG`, which references the same function. + +### fixing wrong configuration of AUDIO feature + +[#8903](https://github.com/qmk/qmk_firmware/pull/8903) and [#8974](https://github.com/qmk/qmk_firmware/pull/8974) + +`audio_avr.c` does not default to any pin; there has to be a #define XX_AUDIO in config.h at some level for Audio to actually work. Otherwise, the Audio code ends up cluttering the firmware, possibly breaking builds because the maximum allowed firmware size is exceeded. + +These changes fix this by disabling Audio on keyboards that have the feature misconfigured, and therefore non-functional. + +Also, add a compile-time error to alert the user to a missing pin-configuration (on AVR boards) when `AUDIO_ENABLE = yes` is set. + + +## Keyboard Refactors + +### Migrating Lily58 to use split_common + +[#6260](https://github.com/qmk/qmk_firmware/pull/6260) + +Modifies the default firmware for Lily58 to use the `split_common` library, instead of including and depending on its own set of libraries for the following functionality: + +- SSD1306 display +- i2c for OLED +- Serial Communication + +This allows current lily58 firmware to advance with updates to the `split_common` library, which is shared with many other split keyboards. + +#### To migrate existing Lily58 firmware: + +[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-445ac369c8717dcd6fc6fc3630836fc1): +- Remove `#define SSD1306OLED` from config.h + + +[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7): +- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` +- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) +- Alternatively, if you did not change the OLED code from that in `default`, you may find it easier to simply copy the [relevant section](https://github.com/qmk/qmk_firmware/blob/4ac310668501ae6786c711ecc8f01f62ddaa1c0b/keyboards/lily58/keymaps/default/keymap.c#L138-L172). Otherwise, the changes you need to make are as follows (sample change [here](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7R138-R173)) +- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L138-L141) the block +```c +#ifdef SSD1306OLED + iota_gfx_init(!has_usb()); // turns on the display +#endif +``` +- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: +```c +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (!is_keyboard_master()) + return OLED_ROTATION_180; // flips the display 180 degrees if offhand + return rotation; +} +``` +- Remove the functions `matrix_scan_user`, `matrix_update` and `iota_gfx_task_user` +- Find/Replace `matrix_render_user(struct CharacterMatrix *matrix)` with `iota_gfx_task_user(void)` +- Find/Replace `is_master` with `is_keyboard_master()` +- For each instance of `matrix_write_ln(matrix, display_fn())`, rewrite it as `oled_write_ln(read_layer_state(), false);` +- For each instance of `matrix_write(matrix, read_logo());`, replace with `oled_write(read_logo(), false);` + +### Refactor zinc to use split_common + +[#7114](https://github.com/qmk/qmk_firmware/pull/7114) and [#9171](https://github.com/qmk/qmk_firmware/pull/9171) + +* Refactor to use split_common and remove split codes under the zinc/revx/ +* Add - backlight RGB LED and/or underglow RGB LED option +* Add - continuous RGB animations feature (between L and R halves) +* Fix - keymap files to adapt to changes + * all authors of keymaps confirmed this PR +* Update - documents and rules.mk + +### Refactor of TKC1800 to use common OLED code + +[#8472](https://github.com/qmk/qmk_firmware/pull/8472) + +Modifies the default firmware for TKC1800 to use the in-built I2C and OLED drivers, instead of including and depending on its own set of libraries for the following functionality: + +- SSD1306 display +- i2c for OLED + +This allows current TKC1800 firmware to advance with updates to those drivers, which are shared with other keyboards. + +#### To migrate existing TKC1800 firmware: + +[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-d10b26e676b4a55cbb00d71955116526): +- Remove `#define SSD1306OLED` from config.h + +[Changes to `tkc1800.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-3b35bd30abe89c8110717c6972cd2cc5): +- Add the following to avoid debug errors on HID_listen if the screen is not present +```c +void keyboard_pre_init_kb(void) { + setPinInputHigh(D0); + setPinInputHigh(D1); + + keyboard_pre_init_user(); +} +``` + +[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-05a2a344ce27e4d045fe68520ccd4771): +- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` +- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) +- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L91-L158) the block +```c +#ifdef SSD1306OLED + iota_gfx_init(!has_usb()); // turns on the display +#endif +``` +- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: +```c +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (!is_keyboard_master()) + return OLED_ROTATION_180; // flips the display 180 degrees if offhand + return rotation; +} +``` +- Remove the function `iota_gfx_task_user` + +### Split HHKB to ANSI and JP layouts and Add VIA support for each + +[#8582](https://github.com/qmk/qmk_firmware/pull/8582) + +- Splits the HHKB codebase into two separate folders `keyboards/hhkb/ansi` and `keyboards/hhkb/jp`. +- Adds VIA Configurator support for both versions. + +#### Migrating existing HHKB keymaps + +- Remove any checks for the `HHKB_JP` definition + - All checks for this definition have been removed, and each version uses the source that is appropriate to that version. +- Move the directory for your keymap into the appropriate `keymaps` directory + - `keyboards/hhkb/ansi/keymaps/` for ANSI HHKBs + - `keyboards/hhkb/jp/keymaps/` for HHKB JPs +- Compile with the new keyboard names + - This PR changes the compilation instructions for the HHKB Alternate Controller. To compile firmware for this controller moving forward, use: + - `make hhkb/ansi` for ANSI-layout HHKBs + - `make hhkb/jp` for HHKB JP keyboards + + +## Keyboard Moves + +- [#8412](https://github.com/qmk/qmk_firmware/pull/8412 "Changing board names to prevent confusion") by blindassassin111 +- [#8499](https://github.com/qmk/qmk_firmware/pull/8499 "Move the Keyboardio Model01 to a keyboardio/ subdir") by algernon +- [#8830](https://github.com/qmk/qmk_firmware/pull/8830 "Move spaceman keyboards") by Spaceman (formerly known as Rionlion100) +- [#8537](https://github.com/qmk/qmk_firmware/pull/8537 "Organizing my keyboards (plaid, tartan, ergoinu)") by hsgw + +Keyboards by Keyboardio, Spaceman, and hsgw move to vendor folders, while PCBs designed by blindassassin111 are renamed. + +Old Name | New Name +:----------------- | :----------------- +2_milk | spaceman/2_milk +at101_blackheart | at101_bh +ergoinu | dm9records/ergoinu +model01 | keyboardio/model01 +omnikey_blackheart | omnikey_bh +pancake | spaceman/pancake +plaid | dm9records/plaid +tartan | dm9records/tartan +z150_blackheart | z150_bh + +If you own one of these PCBs, please use the new names to compile your firmware moving forward. + + +## Keycode Migration PRs + +[#8954](https://github.com/qmk/qmk_firmware/pull/8954 "Migrate `ACTION_LAYER_TOGGLE` to `TG()`"), [#8957](https://github.com/qmk/qmk_firmware/pull/8957 "Migrate `ACTION_MODS_ONESHOT` to `OSM()`"), [#8958](https://github.com/qmk/qmk_firmware/pull/8958 "Migrate `ACTION_DEFAULT_LAYER_SET` to `DF()`"), [#8959](https://github.com/qmk/qmk_firmware/pull/8959 "Migrate `ACTION_LAYER_MODS` to `LM()`"), [#8968](https://github.com/qmk/qmk_firmware/pull/8968 "Migrate `ACTION_MODS_TAP_KEY` to `MT()`"), [#8977](https://github.com/qmk/qmk_firmware/pull/8977 "Migrate miscellaneous `fn_actions` entries"), and [#8979](https://github.com/qmk/qmk_firmware/pull/8979 "Migrate `ACTION_MODS_KEY` to chained mod keycodes") + +Authored by fauxpark, these pull requests remove references to deprecated TMK macros that have been superseded by native QMK keycodes. + +Old `fn_actions` action | New QMK keycode +:---------------------- | :-------------- +`ACTION_DEFAULT_LAYER_SET(layer)` | `DF(layer)` +`ACTION_LAYER_MODS(layer, mod)` | `LM(layer, mod)` +`ACTION_LAYER_ONESHOT(mod)` | `OSL(mod)` +`ACTION_LAYER_TOGGLE(layer)` | `TG(layer)` +`ACTION_MODS_ONESHOT(mod)` | `OSM(mod)` +`ACTION_MODS_TAP_KEY(mod, kc)` | `MT(mod, kc)` +`ACTION_MODS_KEY(mod, kc)`
e.g. `ACTION_MODS_KEY(MOD_LCTL, KC_0)` | `MOD(kc)`
e.g. `LCTL(KC_0)` diff --git a/ChangeLog/20200829.md b/ChangeLog/20200829.md new file mode 100644 index 00000000000..00e0bd1a287 --- /dev/null +++ b/ChangeLog/20200829.md @@ -0,0 +1,148 @@ +# QMK Breaking Change - 2020 Aug 29 Changelog + +Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. + + +## Changes Requiring User Action :id=changes-requiring-user-action + +### Relocated Keyboards :id-relocated-keyboards + +#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547)) +#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635)) + +Keyboards released by The Key Company and keyboards designed by flehrad have moved to vendor folders. If you own any of the keyboards listed below, please use the new names to compile your firmware moving forward. + +Old Name | New Name +:--------------------- | :------------------ +candybar/lefty | tkc/candybar/lefty +candybar/righty | tkc/candybar/righty +m0lly | tkc/m0lly +tkc1800 | tkc/tkc1800 +bigswitch | flehrad/bigswitch +handwired/downbubble | flehrad/downbubble +handwired/numbrero | flehrad/numbrero +snagpad | flehrad/snagpad +handwired/tradestation | flehrad/tradestation + +### Updated Keyboard Codebases :id=keyboard-updates + +#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754)) + +This pull request changes the configuration for Keebio split boards to use the same RGB strip wiring for each half, which provides the following improvements: + +* Easier wiring due to one fewer wire needed (the wire between left DOut to extra data pin) and the fact that wiring is the same for both halves. +* RGB LEDs can be controlled by each half now instead of just master half. +* Extra data line is freed up to allow for I2C usage instead of serial. + +If you have customized the value of `RGBLED_SPLIT` for your keymap, you will need to undefine it using `#undef RGBLED_SPLIT` before defining it to your customized value. + +This change affects: + +* BFO-9000 +* Fourier +* Iris rev2 +* Levinson, revs. 1 and 2 +* Nyquist, revs. 1 and 2 +* Quefrency rev1 +* Viterbi, revs. 1 and 2 + +### Changes to Core Functionality :id=core-updates + +* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318)) + +Allows the Combo feature to support more than 256 combos. + +Any fork that uses `process_combo_event` needs to update the function's first argument to `uint16_t`: + +* Old function: `void process_combo_event(uint8_t combo_index, bool pressed)` +* New function: `void process_combo_event(uint16_t combo_index, bool pressed)` + + +## Core Changes :id=core-changes + +### Fixes :id=core-fixes + +* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174)) +* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987)) + +### Additions and Enhancements :id=core-additions + +* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471)) + * Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon. + * Affects STM32L4+ devices, as well as the soon-to-be-supported-by-QMK STM32G4/H7 families. + * Tested on F303/Proton C (ChibiOS v19, non-DMAMUX), G474 (ChibiOS v20, with DMAMUX). +* dual-bank STM32 bootloader support ([#8778](https://github.com/qmk/qmk_firmware/pull/8778) and [#9738](https://github.com/qmk/qmk_firmware/pull/9738)) + * Adds support for STM32 dual-bank flash bootloaders, by toggling a GPIO during early init in order to charge an RC circuit attached to `BOOT0`. + * The main rationale behind this is that dual-bank STM32 devices unconditionally execute user-mode code, regardless of whether or not the user-mode code jumps to the bootloader. If either flash bank is valid (and `BOOT0` is low), then the built-in bootloader will skip any sort of DFU. + * This PR allows for the initialisation sequencing to charge the RC circuit based on the example circuit posted on Discord, effectively pulling `BOOT0` high before issuing the system reset. As the RC circuit takes a while to discharge, the system reset executes the ROM bootloader which subsequently sees `BOOT0` high, and starts executing the DFU routines. + * Tested with STM32L082 (with current QMK+current ChibiOS), and STM32G474 (against ChibiOS 20.x). +* update Space Cadet and Tap Dance features to use Custom Tapping Term when appropriate ([#6259](https://github.com/qmk/qmk_firmware/pull/6259)) + * For the Tap Dance feature, this completely removes the need for the `ACTION_TAP_DANCE_FN_ADVANCED_TIME` dance. +* HID Joystick Interface ([#4226](https://github.com/qmk/qmk_firmware/pull/4226) and [#9949](https://github.com/qmk/qmk_firmware/pull/9949 "Fix Joystick Compile Issues")) + * This implements a joystick feature, including a joystick_task function called from TMK, specific keycodes for joystick buttons and a USB HID interface. + * Tested on V-USB backend and Proton C; compiles but untested on LUFA. + * In order to test, you have to add `JOYSTICK_ENABLE = yes` to your `rules.mk` and + ```c + #define JOYSTICK_BUTTON_COUNT 8 + #define JOYSTICK_AXES_COUNT 2 + ``` + in your config.h. +* Christmas RGB Underglow animation now fades between green and red ([#7648](https://github.com/qmk/qmk_firmware/pull/7648)) + * `RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL` has been greatly decreased; please check your animation if you have customized this value. +* layer state now initializes on startup ([#8318](https://github.com/qmk/qmk_firmware/pull/8318)) + * This should produce more consistent behavior between the two functions and layer masks. +* added support for HSV->RGB conversion without using CIE curve ([#9856](https://github.com/qmk/qmk_firmware/pull/9856)) +* added NOEEPROM functions for RGB Matrix ([#9487](https://github.com/qmk/qmk_firmware/pull/9487)) + * Added eeprom_helpers for toggle, mode, sethsv, speed, similar to rgblight versions. + * Added set_speed function. + * Added helper functions, similar to those in rgblight, in order to add NOEEPROM versions of toggle, step, hue, sat, val, and speed. + * Minor: spelling correction for EEPROM in a debug message. +* flashing firmware using `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink) is now supported ([#9964](https://github.com/qmk/qmk_firmware/pull/9964)) +* add ability to dump all makefile variables for the specified target ([#8256](https://github.com/qmk/qmk_firmware/pull/8256)) + * Adds a new subtarget to builds, `dump_vars`, which allows for printing out all the variables that make knows about, after all substitutions occur. + * Example: `make handwired/onekey/proton_c:default:dump_vars` +* add ability to change the Auto Shift timeout in real time ([#8441](https://github.com/qmk/qmk_firmware/pull/8441)) +* added a timer implementation for backlight on ChibiOS ([#8291](https://github.com/qmk/qmk_firmware/pull/8291)) +* added a third endpoint to V-USB keyboards ([#9020](https://github.com/qmk/qmk_firmware/pull/9020)) +* added a method to read the OLED display buffer from user space ([#8777](https://github.com/qmk/qmk_firmware/pull/8777)) +* K-Type refactor ([#9864](https://github.com/qmk/qmk_firmware/pull/9864)) + * The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature. +* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169)) + +### Clean-ups and Optimizations :id=core-optimizations + +* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284)) +* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315)) + * Start of the consolidation work to move the ChibiOS board definitions as well as the default set of configuration files for existing board definitions used by keyboards. + * Uses `/platforms/chibios` as previously discussed on discord. + * Consolidates the Proton C configs into the generic F303 definitions. + * Allows for defining a default set of `chconf.h`, `halconf.h`, and `mcuconf.h` files within the platform definition, which is able to be overridden by the keyboard directly, though include path ordering. + * Adds template `chconf.h`, `halconf.h`, `mcuconf.h`, and `board.h` that can be dropped into a keyboard directory, in order to override rather than replace the entire contents of the respective files. + * Removed Proton C QMK board definitions, falling back to ChibiOS board definitions with QMK overrides. +* Various tidy-ups for USB descriptor code ([#9005](https://github.com/qmk/qmk_firmware/pull/9005)) + * Renamed `keyboard_led_stats` in lufa.c and ChibiOS usb_main.c to `keyboard_led_state`, as well as `vusb_keyboard_leds`, for consistency + * Formatted CDC and MIDI descriptors better + * Removed `ENDPOINT_CONFIG` macro, it seems pointless and removes the need for endpoint address defines in the middle of the endpoint numbering enum + * Fixed (possibly?) V-USB `GET_REPORT` request handling. Not sure about this one, but the existing code appears to always return an empty report - now `send_keyboard` sets this variable to the current report, matching what the LUFA code does. +* converted `CONSUMER2BLUEFRUIT()` and `CONSUMER2RN42()` macros to static inline functions ([#9055](https://github.com/qmk/qmk_firmware/pull/9055)) +* Additional cleanups for V-USB code ([#9310](https://github.com/qmk/qmk_firmware/pull/9310)) + * Removing the UART stuff entirely, now that we have Console support. Also fixing up various other things; switching some `debug()` calls to `dprintf()`, moved `raw_hid_report` out of the way so that we can implement the shared endpoint stuff. +* removed inclusion of `adafruit_ble.h` from `ssd1306.c` ([#9355](https://github.com/qmk/qmk_firmware/pull/9355)) +* `outputselect.c` is no longer compiled if Bluetooth is disabled ([#9356](https://github.com/qmk/qmk_firmware/pull/9356)) +* `analogRead()` deprecated in favor of `analogReadPin()` ([#9023](https://github.com/qmk/qmk_firmware/pull/9023)) +* forcibly disable NKRO on V-USB controllers ([#9054](https://github.com/qmk/qmk_firmware/pull/9054)) +* removed warning if running backlight on STM32F072 ([#10040](https://github.com/qmk/qmk_firmware/pull/10040)) +* removed unused CORTEX_VTOR_INIT rules.mk option ([#10053](https://github.com/qmk/qmk_firmware/pull/10053)) +* improved handling for enabling Link Time Optimization ([#9832](https://github.com/qmk/qmk_firmware/pull/9832)) +* streamline rules for supporting Kiibohd bootloader ([#10129](https://github.com/qmk/qmk_firmware/pull/10129)) +* Define `STM32_DMA_REQUIRED` when using DMA-based WS2812 driver on STM32 ([#10127](https://github.com/qmk/qmk_firmware/pull/10127)) +* fix DMA stream ID calculation in ws2812_pwm ([#10008](https://github.com/qmk/qmk_firmware/pull/10008)) +* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103)) + + +## QMK Infrastructure and Internals :id=qmk-internals + +* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308)) + * Actually fetch the branch we're attempting to compare against. +* Run `qmk cformat` on `develop` branch ([#9501](https://github.com/qmk/qmk_firmware/pull/9501)) +* minor refactor of Bluetooth API ([#9905](https://github.com/qmk/qmk_firmware/pull/9905)) diff --git a/README.md b/README.md new file mode 100644 index 00000000000..4fd87268858 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Quantum Mechanical Keyboard Firmware + +[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## What is QMK Firmware? + +QMK (*Quantum Mechanical Keyboard*) is an open source community centered around developing computer input devices. The community encompasses all sorts of input devices, such as keyboards, mice, and MIDI devices. A core group of collaborators maintains [QMK Firmware](https://github.com/qmk/qmk_firmware), [QMK Configurator](https://config.qmk.fm), [QMK Toolbox](https://github.com/qmk/qmk_toolbox), [qmk.fm](https://qmk.fm), and this documentation with the help of community members like you. + +## Get Started + +Totally new to QMK? There are two ways to get started: + +* Basic: [QMK Configurator](https://config.qmk.fm) + * Just select your keyboard from the dropdown and program your keyboard. + * We have an [introductory video](https://www.youtube.com/watch?v=-imgglzDMdY) you can watch. + * There is also an overview [document you can read](newbs_building_firmware_configurator.md). +* Advanced: [Use The Source](newbs.md) + * More powerful, but harder to use + +## Make It Yours + +QMK has lots of [features](features.md) to explore, and a good deal of reference documentation to dig through. Most features are taken advantage of by modifying your [keymap](keymap.md), and changing the [keycodes](keycodes.md). + +## Need help? + +Check out the [support page](support.md) to see how you can get help using QMK. + +## Give Back + +There are a lot of ways you can contribute to the QMK Community. The easiest way to get started is to use it and spread the word to your friends. + +* Help people out on our forums and chat rooms: + * [/r/olkb](https://www.reddit.com/r/olkb/) + * [Discord Server](https://discord.gg/Uq7gcHh) +* Contribute to our documentation by clicking "Edit This Page" at the bottom +* [Translate our documentation into your language](translating.md) +* [Report a bug](https://github.com/qmk/qmk_firmware/issues/new/choose) +* [Open a Pull Request](contributing.md) diff --git a/_langs.md b/_langs.md new file mode 100644 index 00000000000..f7b375fb945 --- /dev/null +++ b/_langs.md @@ -0,0 +1,9 @@ +- Translations + - [:uk: English](/) + - [:cn: 中文](/zh-cn/) + - [:es: Español](/es/) + - [:fr: Français](/fr-fr/) + - [:he: עברית](/he-il/) + - [:brazil: Português](/pt-br/) + - [:ru: Русский](/ru-ru/) + - [:jp: 日本語](/ja/) diff --git a/_summary.md b/_summary.md new file mode 100644 index 00000000000..44030d812d4 --- /dev/null +++ b/_summary.md @@ -0,0 +1,180 @@ +* Tutorial + * [Introduction](newbs.md) + * [Setup](newbs_getting_started.md) + * [Building Your First Firmware](newbs_building_firmware.md) + * [Flashing Firmware](newbs_flashing.md) + * [Testing and Debugging](newbs_testing_debugging.md) + * [Getting Help/Support](support.md) + * [Other Resources](newbs_learn_more_resources.md) + * [Syllabus](syllabus.md) + +* FAQs + * [General FAQ](faq_general.md) + * [Build/Compile QMK](faq_build.md) + * [Debugging/Troubleshooting QMK](faq_debug.md) + * [Keymap FAQ](faq_keymap.md) + * [Glossary](reference_glossary.md) + +* Configurator + * [Overview](newbs_building_firmware_configurator.md) + * [Step by Step](configurator_step_by_step.md) + * [Troubleshooting](configurator_troubleshooting.md) + * QMK API + * [Overview](api_overview.md) + * [API Documentation](api_docs.md) + * [Keyboard Support](reference_configurator_support.md) + * [Adding Default Keymaps](configurator_default_keymaps.md) + +* CLI + * [Overview](cli.md) + * [Configuration](cli_configuration.md) + * [Commands](cli_commands.md) + +* Using QMK + * Guides + * [Customizing Functionality](custom_quantum_functions.md) + * [Driver Installation with Zadig](driver_installation_zadig.md) + * [Keymap Overview](keymap.md) + * Development Environments + * [Docker Guide](getting_started_docker.md) + * [Vagrant Guide](getting_started_vagrant.md) + * Flashing + * [Flashing](flashing.md) + * [Flashing ATmega32A (ps2avrgb)](flashing_bootloadhid.md) + * IDEs + * [Using Eclipse with QMK](other_eclipse.md) + * [Using VSCode with QMK](other_vscode.md) + * Git Best Practices + * [Introduction](newbs_git_best_practices.md) + * [Your Fork](newbs_git_using_your_master_branch.md) + * [Merge Conflicts](newbs_git_resolving_merge_conflicts.md) + * [Fixing Your Branch](newbs_git_resynchronize_a_branch.md) + * Keyboard Building + * [Hand Wiring Guide](hand_wire.md) + * [ISP Flashing Guide](isp_flashing_guide.md) + + * Simple Keycodes + * [Full List](keycodes.md) + * [Basic Keycodes](keycodes_basic.md) + * [Language-Specific Keycodes](reference_keymap_extras.md) + * [Modifier Keys](feature_advanced_keycodes.md) + * [Quantum Keycodes](quantum_keycodes.md) + + * Advanced Keycodes + * [Command](feature_command.md) + * [Dynamic Macros](feature_dynamic_macros.md) + * [Grave Escape](feature_grave_esc.md) + * [Leader Key](feature_leader_key.md) + * [Mod-Tap](mod_tap.md) + * [Macros](feature_macros.md) + * [Mouse Keys](feature_mouse_keys.md) + * [Space Cadet Shift](feature_space_cadet.md) + * [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md) + + * Software Features + * [Auto Shift](feature_auto_shift.md) + * [Combos](feature_combo.md) + * [Debounce API](feature_debounce_type.md) + * [Key Lock](feature_key_lock.md) + * [Layers](feature_layers.md) + * [One Shot Keys](one_shot_keys.md) + * [Pointing Device](feature_pointing_device.md) + * [Raw HID](feature_rawhid.md) + * [Swap Hands](feature_swap_hands.md) + * [Tap Dance](feature_tap_dance.md) + * [Tap-Hold Configuration](tap_hold.md) + * [Terminal](feature_terminal.md) + * [Unicode](feature_unicode.md) + * [Userspace](feature_userspace.md) + * [WPM Calculation](feature_wpm.md) + + * Hardware Features + * Displays + * [HD44780 LCD Controller](feature_hd44780.md) + * [OLED Driver](feature_oled_driver.md) + * Lighting + * [Backlight](feature_backlight.md) + * [LED Matrix](feature_led_matrix.md) + * [RGB Lighting](feature_rgblight.md) + * [RGB Matrix](feature_rgb_matrix.md) + * [Audio](feature_audio.md) + * [Bluetooth](feature_bluetooth.md) + * [Bootmagic](feature_bootmagic.md) + * [Custom Matrix](custom_matrix.md) + * [DIP Switch](feature_dip_switch.md) + * [Encoders](feature_encoders.md) + * [Haptic Feedback](feature_haptic_feedback.md) + * [Joystick](feature_joystick.md) + * [LED Indicators](feature_led_indicators.md) + * [Proton C Conversion](proton_c_conversion.md) + * [PS/2 Mouse](feature_ps2_mouse.md) + * [Split Keyboard](feature_split_keyboard.md) + * [Stenography](feature_stenography.md) + * [Thermal Printer](feature_thermal_printer.md) + * [Velocikey](feature_velocikey.md) + +* Developing QMK + * [PR Checklist](pr_checklist.md) + * Breaking Changes + * [Overview](breaking_changes.md) + * [My Pull Request Was Flagged](breaking_changes_instructions.md) + * History + * [2020 Aug 29](ChangeLog/20200829.md) + * [2020 May 30](ChangeLog/20200530.md) + * [2020 Feb 29](ChangeLog/20200229.md) + * [2019 Aug 30](ChangeLog/20190830.md) + + * C Development + * [ARM Debugging Guide](arm_debugging.md) + * [AVR Processors](hardware_avr.md) + * [Coding Conventions](coding_conventions_c.md) + * [Compatible Microcontrollers](compatible_microcontrollers.md) + * [Drivers](hardware_drivers.md) + * [ADC Driver](adc_driver.md) + * [I2C Driver](i2c_driver.md) + * [SPI Driver](spi_driver.md) + * [WS2812 Driver](ws2812_driver.md) + * [EEPROM Driver](eeprom_driver.md) + * ['serial' Driver](serial_driver.md) + * [GPIO Controls](internals_gpio_control.md) + * [Keyboard Guidelines](hardware_keyboard_guidelines.md) + + * Python Development + * [Coding Conventions](coding_conventions_python.md) + * [QMK CLI Development](cli_development.md) + + * Configurator Development + * QMK API + * [Development Environment](api_development_environment.md) + * [Architecture Overview](api_development_overview.md) + + * Hardware Platform Development + * Arm/ChibiOS + * [Selecting an MCU](platformdev_selecting_arm_mcu.md) + * [Early initialization](platformdev_chibios_earlyinit.md) + + * QMK Reference + * [Contributing to QMK](contributing.md) + * [Translating the QMK Docs](translating.md) + * [Config Options](config_options.md) + * [Make Documentation](getting_started_make_guide.md) + * [Documentation Best Practices](documentation_best_practices.md) + * [Documentation Templates](documentation_templates.md) + * [Community Layouts](feature_layouts.md) + * [Unit Testing](unit_testing.md) + * [Useful Functions](ref_functions.md) + * [info.json Format](reference_info_json.md) + + * For a Deeper Understanding + * [How Keyboards Work](how_keyboards_work.md) + * [How a Matrix Works](how_a_matrix_works.md) + * [Understanding QMK](understanding_qmk.md) + + * QMK Internals (In Progress) + * [Defines](internals_defines.md) + * [Input Callback Reg](internals_input_callback_reg.md) + * [Midi Device](internals_midi_device.md) + * [Midi Device Setup Process](internals_midi_device_setup_process.md) + * [Midi Util](internals_midi_util.md) + * [Send Functions](internals_send_functions.md) + * [Sysex Tools](internals_sysex_tools.md) diff --git a/adc_driver.md b/adc_driver.md new file mode 100644 index 00000000000..6e3d513863b --- /dev/null +++ b/adc_driver.md @@ -0,0 +1,150 @@ +# ADC Driver + +QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders.md). + +This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision. + +## Usage + +To use this driver, add the following to your `rules.mk`: + +```make +SRC += analog.c +``` + +Then place this include at the top of your code: + +```c +#include "analog.h" +``` + +## Channels + +### AVR + +|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P| +|-------|-------------|-------------|---------|----------| +|0 |`F0` |`F0` |`A0` |`C0` | +|1 |`F1` |`F1` |`A1` |`C1` | +|2 |`F2` | |`A2` |`C2` | +|3 |`F3` | |`A3` |`C3` | +|4 |`F4` |`F4` |`A4` |`C4` | +|5 |`F5` |`F5` |`A5` |`C5` | +|6 |`F6` |`F6` |`A6` |* | +|7 |`F7` |`F7` |`A7` |* | +|8 | |`D4` | | | +|9 | |`D6` | | | +|10 | |`D7` | | | +|11 | |`B4` | | | +|12 | |`B5` | | | +|13 | |`B6` | | | + +\* The ATmega328/P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these. + +### ARM + +Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC. + +Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-indexed, whereas the F3 has 4 ADCs and the channels are 1-indexed. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation. + +|ADC|Channel|STM32F0xx|STM32F3xx| +|---|-------|---------|---------| +|1 |0 |`A0` | | +|1 |1 |`A1` |`A0` | +|1 |2 |`A2` |`A1` | +|1 |3 |`A3` |`A2` | +|1 |4 |`A4` |`A3` | +|1 |5 |`A5` |`F4` | +|1 |6 |`A6` |`C0` | +|1 |7 |`A7` |`C1` | +|1 |8 |`B0` |`C2` | +|1 |9 |`B1` |`C3` | +|1 |10 |`C0` |`F2` | +|1 |11 |`C1` | | +|1 |12 |`C2` | | +|1 |13 |`C3` | | +|1 |14 |`C4` | | +|1 |15 |`C5` | | +|1 |16 | | | +|2 |1 | |`A4` | +|2 |2 | |`A5` | +|2 |3 | |`A6` | +|2 |4 | |`A7` | +|2 |5 | |`C4` | +|2 |6 | |`C0` | +|2 |7 | |`C1` | +|2 |8 | |`C2` | +|2 |9 | |`C3` | +|2 |10 | |`F2` | +|2 |11 | |`C5` | +|2 |12 | |`B2` | +|2 |13 | | | +|2 |14 | | | +|2 |15 | | | +|2 |16 | | | +|3 |1 | |`B1` | +|3 |2 | |`E9` | +|3 |3 | |`E13` | +|3 |4 | | | +|3 |5 | | | +|3 |6 | |`E8` | +|3 |7 | |`D10` | +|3 |8 | |`D11` | +|3 |9 | |`D12` | +|3 |10 | |`D13` | +|3 |11 | |`D14` | +|3 |12 | |`B0` | +|3 |13 | |`E7` | +|3 |14 | |`E10` | +|3 |15 | |`E11` | +|3 |16 | |`E12` | +|4 |1 | |`E14` | +|4 |2 | |`B12` | +|4 |3 | |`B13` | +|4 |4 | |`B14` | +|4 |5 | |`B15` | +|4 |6 | |`E8` | +|4 |7 | |`D10` | +|4 |8 | |`D11` | +|4 |9 | |`D12` | +|4 |10 | |`D13` | +|4 |11 | |`D14` | +|4 |12 | |`D8` | +|4 |13 | |`D9` | +|4 |14 | | | +|4 |15 | | | +|4 |16 | | | + +## Functions + +### AVR + +|Function |Description | +|----------------------------|-------------------------------------------------------------------------------------------------------------------| +|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.| +|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `F6` for ADC6 on the ATmega32U4. | +|`pinToMux(pin)` |Translates a given pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". | +|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. | + +### ARM + +|Function |Description | +|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.| +|`analogReadPinAdc(pin, adc)`|Reads the value from the specified pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function. | +|`pinToMux(pin)` |Translates a given pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)". | +|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and ADC combination. See your MCU's datasheet for more information. | + +## Configuration + +## ARM + +The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options. + +|`#define` |Type |Default |Description | +|---------------------|------|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |If `true`, then the implementation will use a circular buffer. | +|`ADC_NUM_CHANNELS` |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`. | +|`ADC_BUFFER_DEPTH` |`int` |`2` |Sets the depth of each result. Since we are only getting a 12-bit result by default, we set this to 2 bytes so we can contain our one value. This could be set to 1 if you opt for an 8-bit or lower result.| +|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. | +|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_12BIT`|The resolution of your result. We choose 12 bit by default, but you can opt for 12, 10, 8, or 6 bit. | diff --git a/api_development_environment.md b/api_development_environment.md new file mode 100644 index 00000000000..50647c42995 --- /dev/null +++ b/api_development_environment.md @@ -0,0 +1,3 @@ +# Development Environment Setup + +To setup a development stack head over to the [qmk_web_stack](https://github.com/qmk/qmk_web_stack). diff --git a/api_development_overview.md b/api_development_overview.md new file mode 100644 index 00000000000..e55d0341006 --- /dev/null +++ b/api_development_overview.md @@ -0,0 +1,44 @@ +# QMK Compiler Development Guide + +This page attempts to introduce developers to the QMK Compiler. It does not go into nitty gritty details- for that you should read code. What this will give you is a framework to hang your understanding on as you read the code. + +# Overview + +The QMK Compile API consists of a few movings parts: + +![Architecture Diagram](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg) + +API Clients interact exclusively with the API service. This is where they submit jobs, check status, and download results. The API service inserts compile jobs into [Redis Queue](https://python-rq.org) and checks both RQ and S3 for the results of those jobs. + +Workers fetch new compile jobs from RQ, compile them, and then upload the source and the binary to an S3 compatible storage engine. + +# Workers + +QMK Compiler Workers are responsible for doing the actual building. When a worker pulls a job from RQ it does several things to complete that job: + +* Make a fresh qmk_firmware checkout +* Use the supplied layers and keyboard metadata to build a `keymap.c` +* Build the firmware +* Zip a copy of the source +* Upload the firmware, source zip, and a metadata file to S3. +* Report the status of the job to RQ + +# API Service + +The API service is a relatively simple Flask application. There are a few main views you should understand. + +## @app.route('/v1/compile', methods=['POST']) + +This is the main entrypoint for the API. A client's interaction starts here. The client POST's a JSON document describing their keyboard, and the API does some (very) basic validation of that JSON before submitting the compile job. + +## @app.route('/v1/compile/<string:job_id>', methods=['GET']) + +This is the most frequently called endpoint. It pulls the job details from redis, if they're still available, or the cached job details on S3 if they're not. + +## @app.route('/v1/compile/<string:job_id>/download', methods=['GET']) + +This method allows users to download the compiled firmware file. + +## @app.route('/v1/compile/<string:job_id>/source', methods=['GET']) + +This method allows users to download the source for their firmware. diff --git a/api_docs.md b/api_docs.md new file mode 100644 index 00000000000..28a7dd71da1 --- /dev/null +++ b/api_docs.md @@ -0,0 +1,68 @@ +# QMK API + +This page describes using the QMK API. If you are an application developer you can use this API to compile firmware for any [QMK](https://qmk.fm) Keyboard. + +## Overview + +This service is an asynchronous API for compiling custom keymaps. You POST some JSON to the API, periodically check the status, and when your firmware has finished compiling you can download the resulting firmware and (if desired) source code for that firmware. + +#### Example JSON Payload: + +```json +{ + "keyboard": "clueboard/66/rev2", + "keymap": "my_awesome_keymap", + "layout": "LAYOUT_all", + "layers": [ + ["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"], + ["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"], + ["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"] + ] +} +``` + +As you can see the payload describes all aspects of a keyboard necessary to create and generate a firmware. Each layer is a single list of QMK keycodes the same length as the keyboard's `LAYOUT` macro. If a keyboard supports mulitple `LAYOUT` macros you can specify which macro to use. + +## Submitting a Compile Job + +To compile your keymap into a firmware simply POST your JSON to the `/v1/compile` endpoint. In the following example we've placed the JSON payload into a file named `json_data`. + +``` +$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" http://api.qmk.fm/v1/compile +{ + "enqueued": true, + "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6" +} +``` + +## Checking The Status + +After submitting your keymap you can check the status using a simple HTTP GET call: + +``` +$ curl http://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6 +{ + "created_at": "Sat, 19 Aug 2017 21:39:12 GMT", + "enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT", + "id": "f5f9b992-73b4-479b-8236-df1deb37c163", + "status": "running", + "result": null +} +``` + +This shows us that the job has made it through the queue and is currently running. There are 5 possible statuses: + +* **failed**: Something about the compiling service has broken. +* **finished**: The compilation is complete and you should check `result` to see the results. +* **queued**: The keymap is waiting for a compilation server to become available. +* **running**: The compilation is in progress and should be complete soon. +* **unknown**: A serious error has occurred and you should [file a bug](https://github.com/qmk/qmk_compiler/issues). + +## Examining Finished Results + +Once your compile job has finished you'll check the `result` key. The value of this key is a hash containing several key bits of information: + +* `firmware_binary_url`: A list of URLs for the the flashable firmware +* `firmware_keymap_url`: A list of URLs for the the `keymap.c` +* `firmware_source_url`: A list of URLs for the full firmware source code +* `output`: The stdout and stderr for this compile job. Errors will be found here. diff --git a/api_overview.md b/api_overview.md new file mode 100644 index 00000000000..91d317f06bc --- /dev/null +++ b/api_overview.md @@ -0,0 +1,15 @@ +# QMK API + +The QMK API provides an asynchronous API that Web and GUI tools can use to compile arbitrary keymaps for any keyboard supported by [QMK](http://qmk.fm/). The stock keymap template supports all QMK keycodes that do not require supporting C code. Keyboard maintainers can supply their own custom templates to enable more functionality. + +## App Developers + +If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs.md). + +## Keyboard Maintainers + +If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support.md) section. + +## Backend Developers + +If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment.md), then check out [Hacking On The API](api_development_overview.md). diff --git a/arm_debugging.md b/arm_debugging.md new file mode 100644 index 00000000000..04887d88b7c --- /dev/null +++ b/arm_debugging.md @@ -0,0 +1,87 @@ +# ARM Debugging using Eclipse + +This page describes how to setup debugging for ARM MCUs using an SWD adapter and open-source/free tools. In this guide we will install GNU MCU Eclipse IDE for C/C++ Developers and OpenOCD together with all the necessary dependencies. + +This guide is catered towards advance users and assumes you can compile an ARM compatible keyboard on your machine using the MAKE flow. + +## Installing the software + +The main objective here is to get the MCU Eclipse IDE correctly installed on our machine. The necessary instructions are derived from [this](https://gnu-mcu-eclipse.github.io/install/) install guide. + +### The xPack Manager + +This tool is a software package manager and it is used to help us get the necessary dependencies. + +XPM runs using Node.js so grab that from [here](https://nodejs.org/en/). After installation, open a terminal and type `npm -v`. A reply with the version number means that the installation was successful. + +XPM installation instructions can be found [here](https://www.npmjs.com/package/xpm) and are OS specific. Entering `xpm --version` to your terminal should return the software version. + +### The ARM Toolchain + +Using XPM it is very easy to install the ARM toolchain. Enter the command `xpm install --global @xpack-dev-tools/arm-none-eabi-gcc`. + +### Windows build tools + +If you are using windows you need to install this! + +`xpm install --global @gnu-mcu-eclipse/windows-build-tools` + +### Programmer/Debugger Drivers + +Now it's time to install your programmer's drivers. This tutorial was made using an ST-Link v2 which you can get from almost anywhere. +If you have an ST-Link the drivers can be found [here](https://www.st.com/en/development-tools/stsw-link009.html) otherwise consult the manufacturer of your tool. + +### OpenOCD + +This dependency allows SWD access from GDB and it is essential for debugging. Run `xpm install --global @xpack-dev-tools/openocd`. + +### Java + +Java is needed by Eclipse so please download it from [here](https://www.oracle.com/technetwork/java/javase/downloads/index.html). + +### GNU MCU Eclipse IDE + +Now its finally time to install the IDE. Use the Release page [here](https://github.com/gnu-mcu-eclipse/org.eclipse.epp.packages/releases/) to get the latest version. + +## Configuring Eclipse + +Open up the Eclipse IDE we just downloaded. To import our QMK directory select File -> Import -> C/C++ -> Existing Code as Makefile Project. Select Next and use Browse to select your QMK folder. In the tool-chain list select ARM Cross GCC and select Finish. + +Now you can see the QMK folder on the left hand side. Right click it and select Properties. On the left hand side, expand MCU and select ARM Toolchains Paths. Press xPack and OK. Repeat for OpenOCD Path and if you are on Windows for Build Tools Path. Select Apply and Close. + +Now its time to install the necessary MCU packages. Go to Packs perspective by selecting Window -> Perspective -> Open Perspective -> Other... -> Packs. Now select the yellow refresh symbol next to the Packs tab. This will take a long time as it is requesting the MCU definitions from various places. If some of the links fail you can probably select Ignore. + +When this finishes you must find the MCU which we will be building/debugging for. In this example I will be using the STM32F3 series MCUs. On the left, select STMicroelectronics -> STM32F3 Series. On the middle window we can see the pack. Right click and select Install. Once that is done we can go back to the default perspective, Window -> Perspective -> Open Perspective -> Other... -> C/C++. + +We need to let eclipse know the device we intent to build QMK on. Right click on the QMK folder -> Properties -> C/C++ Build -> Settings. Select the Devices tab and under Devices select the appropriate variant of your MCU. For my example it is STM32F303CC + +While we are here let's setup the build command as well. Select C/C++ Build and then the Behavior tab. On the Build command, replace `all` with your necessary make command. For example for a rev6 Planck with the default keymap this would be `planck/rev6:default`. Select Apply and Close. + +## Building + +If you have setup everything correctly pressing the hammer button should build the firmware for you and a .bin file should appear. + +## Debugging + +### Connecting the Debugger + +ARM MCUs use the Single Wire Debug (SWD) protocol which comprises of the clock (SWCLK) signal and the data (SWDIO) signal. Connecting this two wires and ground should be enough to allow full manipulation of the MCU. Here we assume that the keyboard will be powered though USB. The RESET signal is not necessary as we can manually assert it using the reset button. For a more advance setup, the SWO signal can be used which pipes printf and scanf asynchronously to the host but for our setup we will ignore it. + +NOTE: Make sure the SWCLK and SWDIO pins are not used in the matrix of your keyboard. If they are you can temporarily switch them for some other pins. + +### Configuring the Debugger + +Right click on your QMK folder, select Debug As -> Debug Configurations... . Here double click on GDB OpenOCD Debugging. Select the Debugger tab and enter the configuration necessary for your MCU. This might take some fiddling and Googling to find out. The default script for the STM32F3 is called `stm32f3discovery.cfg`. To let OpenOCD know, in the Config options enter `-f board/stm32f3discovery.cfg`. + +NOTE: In my case this configuration script requires editing to disable the reset assertion. The locations of the scripts can be found in the actual executable field usually under the path `openocd/version/.content/scripts/board`. Here I edited `reset_config srst_only` to `reset_config none`. + +Select Apply and Close. + +### Running the Debugger. + +Reset your keyboard. + +Press the bug icon and if all goes well you should soon find yourself in the Debug perspective. Here the program counter will pause at the beginning of the main function and wait for you to press Play. Most of the features of all debuggers work on Arm MCUs but for exact details Google is your friend! + + +Happy debugging! diff --git a/breaking_changes.md b/breaking_changes.md new file mode 100644 index 00000000000..abace81648c --- /dev/null +++ b/breaking_changes.md @@ -0,0 +1,110 @@ +# Breaking Changes + +This document describes QMK's Breaking Change process. A Breaking Change is any change which modifies how QMK behaves in a way that in incompatible or potentially dangerous. We limit these changes so that users can have confidence that updating their QMK tree will not break their keymaps. + +The breaking change period is when we will merge PR's that change QMK in dangerous or unexpected ways. There is a built-in period of testing so we are confident that any problems caused are rare or unable to be predicted. + +## What has been included in past Breaking Changes? + +* [2020 Aug 29](ChangeLog/20200829.md) +* [2020 May 30](ChangeLog/20200530.md) +* [2020 Feb 29](ChangeLog/20200229.md) +* [2019 Aug 30](ChangeLog/20190830.md) + +## When is the next Breaking Change? + +The next Breaking Change is scheduled for November 28, 2020. + +### Important Dates + +* [x] 2020 Aug 29 - `develop` is created. It will be rebased weekly. +* [ ] 2020 Oct 31 - `develop` closed to new PR's. +* [ ] 2020 Oct 31 - Call for testers. +* [ ] 2020 Nov 26 - `master` is locked, no PR's merged. +* [ ] 2020 Nov 28 - Merge `develop` to `master`. +* [ ] 2020 Nov 28 - `master` is unlocked. PR's can be merged again. + +## What changes will be included? + +To see a list of breaking change candidates you can look at the [`breaking_change` label](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Abreaking_change+is%3Apr). New changes might be added between now and when `develop` is closed, and a PR with that label applied is not guaranteed to be merged. + +If you want your breaking change to be included in this round you need to create a PR with the `breaking_change` label and have it accepted before `develop` closes. After `develop` closes no new breaking changes will be accepted. + +Criteria for acceptance: + +* PR is complete and ready to merge +* PR has a ChangeLog + +# Checklists + +This section documents various processes we use when running the Breaking Changes process. + +## Rebase `develop` from `master` + +This is run every Friday while `develop` is open. + +Process: + +``` +cd qmk_firmware +git checkout master +git pull --ff-only +git checkout develop +git rebase master +git push --force +``` + +## Creating the `develop` branch + +This happens immediately after the previous `develop` branch is merged. + +* `qmk_firmware` git commands + * [ ] `git checkout master` + * [ ] `git pull --ff-only` + * [ ] `git checkout -b develop` + * [ ] Edit `readme.md` + * [ ] Add a big notice at the top that this is a testing branch. + * [ ] Include a link to this document + * [ ] `git commit -m 'Branch point for Breaking Change'` + * [ ] `git tag breakpoint___
` + * [ ] `git tag ` # Prevent the breakpoint tag from confusing version incrementing + * [ ] `git push origin develop` + * [ ] `git push --tags` + +## 4 Weeks Before Merge + +* `develop` is now closed to new PR's, only fixes for current PR's may be merged +* Post call for testers + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## 1 Week Before Merge + +* Announce that master will be closed from <2 Days Before> to + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## 2 Days Before Merge + +* Announce that master is closed for 2 days + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## Day Of Merge + +* `qmk_firmware` git commands + * [ ] `git checkout develop` + * [ ] `git pull --ff-only` + * [ ] `git rebase origin/master` + * [ ] Edit `readme.md` + * [ ] Remove the notes about `develop` + * [ ] Roll up the ChangeLog into one file. + * [ ] `git commit -m 'Merge point for Breaking Change'` + * [ ] `git push origin develop` +* GitHub Actions + * [ ] Create a PR for `develop` + * [ ] Make sure travis comes back clean + * [ ] Merge `develop` PR diff --git a/breaking_changes_instructions.md b/breaking_changes_instructions.md new file mode 100644 index 00000000000..d835671556d --- /dev/null +++ b/breaking_changes_instructions.md @@ -0,0 +1,42 @@ +# Breaking Changes: My Pull Request Was Flagged + +A QMK member may have replied to your pull request stating that your submission is a breaking change. In their judgment, the changes you have proposed have greater implications for either QMK, or its users. + +Some things that may cause a pull request to be flagged are: + +- **Edits to User Keymaps** + A user may submit their keymap to QMK, then some time later open a pull request with further updates, only to find it can't be merged because it was edited in the `qmk/qmk_firmware` repository. As not all users are proficient at using Git or GitHub, the user may find themself unable to fix the issue on their own. +- **Changes to Expected Behavior** + Changes to QMK behavior may cause users to believe their hardware or QMK is broken if they flash new firmware that incorporates changes to existing QMK features, and find themselves without a means to restore the desired behavior. +- **Changes Requiring User Action** + Changes may also require action to be taken by users, such as updating a toolchain or taking some action in Git. +- **Changes Necessitating Increased Scrutiny** + On occasion, a submission may have implications for QMK as a project. This could be copyright/licensing issues, coding conventions, large feature overhauls, "high-risk" changes that need wider testing by our community, or something else entirely. +- **Changes Requiring Communication to End Users** + This includes warnings about future deprecations, outdated practices, and anything else that needs to be communicated but doesn't fit into one of the above categories. + +## What Do I Do? + +If it is determined that your submission is a breaking change, there are a few things you can do to smooth the process: + +### Consider Splitting Up Your PR + +If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code. + +### Contribute a ChangeLog Entry + +We require submissions that go through the Breaking Change process to include a changelog entry. The entry should be a short summary of the changes your pull request makes – [each section here started as a changelog](ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft"). + +Your changelog should be located at `docs/ChangeLog/YYYYMMDD/PR####.md`, where `YYYYMMDD` is the date on which QMK's breaking change branch – usually named `develop` – will be merged into the `master` branch, and `####` is the number of your pull request. + +If your submission requires action on the part of users, your changelog should instruct users what action(s) must be taken, or link to a location that does so. + +### Document Your Changes + +Understanding the purpose for your submission, and possible implications or actions it will require can make the review process more straightforward. A changelog may suffice for this purpose, but more extensive changes may require a level of detail that is ill-suited for a changelog. + +Commenting on your pull request and being responsive to questions, comments, and change requests is much appreciated. + +### Ask for Help + +Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/Uq7gcHh). diff --git a/cli.md b/cli.md new file mode 100644 index 00000000000..8684479d0c1 --- /dev/null +++ b/cli.md @@ -0,0 +1,38 @@ +# QMK CLI :id=qmk-cli + +## Overview :id=overview + +The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more. + +### Requirements :id=requirements + +QMK requires Python 3.6 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI. + +### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew + +If you have installed [Homebrew](https://brew.sh) you can tap and install QMK: + +``` +brew install qmk/qmk/qmk +export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` +qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment +``` + +### Install Using pip :id=install-using-easy_install-or-pip + +If your system is not listed above you can install QMK manually. First ensure that you have Python 3.6 (or later) installed and have installed pip. Then install QMK with this command: + +``` +python3 -m pip install qmk +export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` +qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment +``` + +### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems + +We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines: + +* Follow best practices for your OS when they conflict with these guidelines + * Document why in a comment when you do deviate +* Install using a virtualenv +* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`. diff --git a/cli_commands.md b/cli_commands.md new file mode 100644 index 00000000000..69df82f9532 --- /dev/null +++ b/cli_commands.md @@ -0,0 +1,339 @@ +# QMK CLI Commands + +# User Commands + +## `qmk compile` + +This command allows you to compile firmware from any directory. You can compile JSON exports from , compile keymaps in the repo, or compile the keyboard in the current working directory. + +This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. + +**Usage for Configurator Exports**: + +``` +qmk compile +``` + +**Usage for Keymaps**: + +``` +qmk compile -kb -km +``` + +**Usage in Keyboard Directory**: + +Must be in keyboard directory with a default keymap, or in keymap directory for keyboard, or supply one with `--keymap ` +``` +qmk compile +``` + +**Usage for building all keyboards that support a specific keymap**: + +``` +qmk compile -kb all -km +``` + +**Example**: +``` +$ qmk config compile.keymap=default +$ cd ~/qmk_firmware/keyboards/planck/rev6 +$ qmk compile +Ψ Compiling keymap with make planck/rev6:default +... +``` +or with optional keymap argument + +``` +$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4 +$ qmk compile -km 66_iso +Ψ Compiling keymap with make clueboard/66/rev4:66_iso +... +``` +or in keymap directory + +``` +$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak +$ qmk compile +Ψ Compiling keymap with make make gh60/satan:colemak +... +``` + +**Usage in Layout Directory**: + +Must be under `qmk_firmware/layouts/`, and in a keymap folder. +``` +qmk compile -kb +``` + +**Example**: +``` +$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi +$ qmk compile -kb dz60 +Ψ Compiling keymap with make dz60:mechmerlin-ansi +... +``` + +## `qmk flash` + +This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default. To specify a different bootloader, use `-bl `. Visit the [Flashing Firmware](flashing.md) guide for more details of the available bootloaders. + +This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. + +**Usage for Configurator Exports**: + +``` +qmk flash -bl +``` + +**Usage for Keymaps**: + +``` +qmk flash -kb -km -bl +``` + +**Listing the Bootloaders** + +``` +qmk flash -b +``` + +## `qmk config` + +This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md). + +**Usage**: + +``` +qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] +``` + +## `qmk doctor` + +This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to. + +**Usage**: + +``` +qmk doctor [-y] [-n] +``` + +**Examples**: + +Check your environment for problems and prompt to fix them: + + qmk doctor + +Check your environment and automatically fix any problems found: + + qmk doctor -y + +Check your environment and report problems only: + + qmk doctor -n + +## `qmk info` + +Displays information about keyboards and keymaps in QMK. You can use this to get information about a keyboard, show the layouts, display the underlying key matrix, or to pretty-print JSON keymaps. + +**Usage**: + +``` +qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD] +``` + +This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. + +**Examples**: + +Show basic information for a keyboard: + + qmk info -kb planck/rev5 + +Show the matrix for a keyboard: + + qmk info -kb ergodox_ez -m + +Show a JSON keymap for a keyboard: + + qmk info -kb clueboard/california -km default + +## `qmk json2c` + +Creates a keymap.c from a QMK Configurator export. + +**Usage**: + +``` +qmk json2c [-o OUTPUT] filename +``` + +## `qmk c2json` + +Creates a keymap.json from a keymap.c. +**Note:** Parsing C source files is not easy, therefore this subcommand may not work your keymap. In some cases not using the C pre-processor helps. + +**Usage**: + +``` +qmk c2json [--no-cpp] [-o OUTPUT] filename +``` + +## `qmk lint` + +Checks over a keyboard and/or keymap and highlights common errors, problems, and anti-patterns. + +**Usage**: + +``` +qmk lint [-km KEYMAP] [-kb KEYBOARD] [--strict] +``` + +This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. + +**Examples**: + +Do a basic lint check: + + qmk lint -kb rominronin/katana60/rev2 + +## `qmk list-keyboards` + +This command lists all the keyboards currently defined in `qmk_firmware` + +**Usage**: + +``` +qmk list-keyboards +``` + +## `qmk list-keymaps` + +This command lists all the keymaps for a specified keyboard (and revision). + +This command is directory aware. It will automatically fill in KEYBOARD if you are in a keyboard directory. + +**Usage**: + +``` +qmk list-keymaps -kb planck/ez +``` + +## `qmk new-keymap` + +This command creates a new keymap based on a keyboard's existing default keymap. + +This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. + +**Usage**: + +``` +qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] +``` + +## `qmk clean` + +This command cleans up the `.build` folder. If `--all` is passed, any .hex or .bin files present in the `qmk_firmware` directory will also be deleted. + +**Usage**: + +``` +qmk clean [-a] +``` + +--- + +# Developer Commands + +## `qmk cformat` + +This command formats C code using clang-format. + +Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b ` + +Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files. + +**Usage for specified files**: + +``` +qmk cformat [file1] [file2] [...] [fileN] +``` + +**Usage for all core files**: + +``` +qmk cformat -a +``` + +**Usage for only changed files against origin/master**: + +``` +qmk cformat +``` + +**Usage for only changed files against branch_name**: + +``` +qmk cformat -b branch_name +``` + +## `qmk docs` + +This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936. + +**Usage**: + +``` +qmk docs [-p PORT] +``` + +## `qmk generate-docs` + +This command allows you to generate QMK documentation locally. It can be uses for general browsing or improving the docs. External tools such as [serve](https://www.npmjs.com/package/serve) can be used to browse the generated files. + +**Usage**: + +``` +qmk generate-docs +``` + +## `qmk kle2json` + +This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite. + +**Usage**: + +``` +qmk kle2json [-f] +``` + +**Examples**: + +``` +$ qmk kle2json kle.txt +☒ File info.json already exists, use -f or --force to overwrite. +``` + +``` +$ qmk kle2json -f kle.txt -f +Ψ Wrote out to info.json +``` + +## `qmk pyformat` + +This command formats python code in `qmk_firmware`. + +**Usage**: + +``` +qmk pyformat +``` + +## `qmk pytest` + +This command runs the python test suite. If you make changes to python code you should ensure this runs successfully. + +**Usage**: + +``` +qmk pytest +``` diff --git a/cli_configuration.md b/cli_configuration.md new file mode 100644 index 00000000000..50f5dc6e280 --- /dev/null +++ b/cli_configuration.md @@ -0,0 +1,121 @@ +# QMK CLI Configuration + +This document explains how `qmk config` works. + +# Introduction + +Configuration for the QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set. + +## Simple Example + +As an example let's look at the command `qmk compile --keyboard clueboard/66/rev4 --keymap default`. + +There are two command line arguments that could be read from configuration instead: + +* `compile.keyboard` +* `compile.keymap` + +Let's set these now: + +``` +$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default +compile.keyboard: None -> clueboard/66/rev4 +compile.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +Now I can run `qmk compile` without specifying my keyboard and keymap each time. + +## Setting User Defaults + +Sometimes you want to share a setting between multiple commands. For example, multiple commands take the argument `--keyboard`. Rather than setting this value for every command you can set a user value which will be used by any command that takes that argument. + +Example: + +``` +$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default +user.keyboard: None -> clueboard/66/rev4 +user.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# CLI Documentation (`qmk config`) + +The `qmk config` command is used to interact with the underlying configuration. When run with no argument it shows the current configuration. When arguments are supplied they are assumed to be configuration tokens, which are strings containing no spaces with the following form: + + [.][=] + +## Setting Configuration Values + +You can set configuration values by putting an equal sign (=) into your config key. The key must always be the full `
.` form. + +Example: + +``` +$ qmk config default.keymap=default +default.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## Reading Configuration Values + +You can read configuration values for the entire configuration, a single key, or for an entire section. You can also specify multiple keys to display more than one value. + +### Entire Configuration Example + + qmk config + +### Whole Section Example + + qmk config compile + +### Single Key Example + + qmk config compile.keyboard + +### Multiple Keys Example + + qmk config user compile.keyboard compile.keymap + +## Deleting Configuration Values + +You can delete a configuration value by setting it to the special string `None`. + +Example: + +``` +$ qmk config default.keymap=None +default.keymap: default -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## Multiple Operations + +You can combine multiple read and write operations into a single command. They will be executed and displayed in order: + +``` +$ qmk config compile default.keymap=default compile.keymap=None +compile.keymap=skully +compile.keyboard=clueboard/66_hotswap/gen1 +default.keymap: None -> default +compile.keymap: skully -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# User Configuration Options + +| Key | Default Value | Description | +|-----|---------------|-------------| +| user.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | +| user.keymap | None | The keymap name (Example: `default`) | +| user.name | None | The user's GitHub username. | + +# All Configuration Options + +| Key | Default Value | Description | +|-----|---------------|-------------| +| compile.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | +| compile.keymap | None | The keymap name (Example: `default`) | +| hello.name | None | The name to greet when run. | +| new_keyboard.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | +| new_keyboard.keymap | None | The keymap name (Example: `default`) | diff --git a/cli_development.md b/cli_development.md new file mode 100644 index 00000000000..07c8f281bac --- /dev/null +++ b/cli_development.md @@ -0,0 +1,219 @@ +# QMK CLI Development + +This document has useful information for developers wishing to write new `qmk` subcommands. + +# Overview + +The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None. + +## Developer mode: + +If you intend to maintain keyboards and/or contribute to QMK, you can enable the CLI's "Developer" mode: + +`qmk config user.developer=True` + +This will allow you to see all available subcommands. +**Note:** You will have to install additional requirements: +```bash +python3 -m pip install -r requirements-dev.txt +``` + +# Subcommands + +[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code. + +Subcommands in the local CLI are always found in `qmk_firmware/lib/python/qmk/cli`. + +Let's start by looking at an example subcommand. This is `lib/python/qmk/cli/hello.py`: + +```python +"""QMK Python Hello World + +This is an example QMK CLI script. +""" +from milc import cli + + +@cli.argument('-n', '--name', default='World', help='Name to greet.') +@cli.subcommand('QMK Hello World.') +def hello(cli): + """Log a friendly greeting. + """ + cli.log.info('Hello, %s!', cli.config.hello.name) +``` + +First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function. + +Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator. + +# User Interaction + +MILC and the QMK CLI have several nice tools for interacting with the user. Using these standard tools will allow you to colorize your text for easier interactions, and allow the user to control when and how that information is displayed and stored. + +## Printing Text + +There are two main methods for outputting text in a subcommand- `cli.log` and `cli.echo()`. They operate in similar ways but you should prefer to use `cli.log.info()` for most general purpose printing. + +You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below. + +Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example. + +You should never use the format operator (`%`) directly, always pass values as arguments. + +### Logging (`cli.log`) + +The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong. + +The default log level is `INFO`. If the user runs `qmk -v ` the default log level will be set to `DEBUG`. + +| Function | Emoji | +|----------|-------| +| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` | +| cli.log.error | `{fg_red}☒{style_reset_all}` | +| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` | +| cli.log.info | `{fg_blue}Ψ{style_reset_all}` | +| cli.log.debug | `{fg_cyan}☐{style_reset_all}` | +| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` | + +### Printing (`cli.echo`) + +Sometimes you simply need to print text outside of the log system. This is appropriate if you are outputting fixed data or writing out something that should never be logged. Most of the time you should prefer `cli.log.info()` over `cli.echo`. + +### Colorizing Text + +You can colorize the output of your text by including color tokens within text. Use color to highlight, not to convey information. Remember that the user can disable color, and your subcommand should still be usable if they do. + +You should generally avoid setting the background color, unless it's integral to what you are doing. Remember that users have a lot of preferences when it comes to their terminal color, so you should pick colors that work well against both black and white backgrounds. + +Colors prefixed with 'fg' will affect the foreground (text) color. Colors prefixed with 'bg' will affect the background color. + +| Color | Background | Extended Background | Foreground | Extended Foreground| +|-------|------------|---------------------|------------|--------------------| +| Black | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} | +| Blue | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} | +| Cyan | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} | +| Green | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} | +| Magenta | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} | +| Red | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} | +| White | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} | +| Yellow | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} | + +There are also control sequences that can be used to change the behavior of +ANSI output: + +| Control Sequences | Description | +|-------------------|-------------| +| {style_bright} | Make the text brighter | +| {style_dim} | Make the text dimmer | +| {style_normal} | Make the text normal (neither `{style_bright}` nor `{style_dim}`) | +| {style_reset_all} | Reset all text attributes to default. (This is automatically added to the end of every string.) | +| {bg_reset} | Reset the background color to the user's default | +| {fg_reset} | Reset the foreground color to the user's default | + +# Arguments and Configuration + +QMK handles the details of argument parsing and configuration for you. When you add a new argument it is automatically incorporated into the config tree based on your subcommand's name and the long name of the argument. You can access this configuration in `cli.config`, using either attribute-style access (`cli.config..`) or dictionary-style access (`cli.config['']['']`). + +Under the hood QMK uses [ConfigParser](https://docs.python.org/3/library/configparser.html) to store configurations. This gives us an easy and straightforward way to represent the configuration in a human-editable way. We have wrapped access to this configuration to provide some nicities that ConfigParser does not normally have. + +## Reading Configuration Values + +You can interact with `cli.config` in all the ways you'd normally expect. For example the `qmk compile` command gets the keyboard name from `cli.config.compile.keyboard`. It does not need to know whether that value came from the command line, an environment variable, or the configuration file. + +Iteration is also supported: + +``` +for section in cli.config: + for key in cli.config[section]: + cli.log.info('%s.%s: %s', section, key, cli.config[section][key]) +``` + +## Setting Configuration Values + +You can set configuration values in the usual ways. + +Dictionary style: + +``` +cli.config['
'][''] = +``` + +Attribute style: + +``` +cli.config.
. = +``` + +## Deleting Configuration Values + +You can delete configuration values in the usual ways. + +Dictionary style: + +``` +del(cli.config['
']['']) +``` + +Attribute style: + +``` +del(cli.config.
.) +``` + +## Writing The Configuration File + +The configuration is not written out when it is changed. Most commands do not need to do this. We prefer to have the user change their configuration deliberitely using `qmk config`. + +You can use `cli.save_config()` to write out the configuration. + +## Excluding Arguments From Configuration + +Some arguments should not be propagated to the configuration file. These can be excluded by adding `arg_only=True` when creating the argument. + +Example: + +``` +@cli.argument('-o', '--output', arg_only=True, help='File to write to') +@cli.argument('filename', arg_only=True, help='Configurator JSON file') +@cli.subcommand('Create a keymap.c from a QMK Configurator export.') +def json_keymap(cli): + pass +``` + +You will only be able to access these arguments using `cli.args`. For example: + +``` +cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output) +``` + +# Testing, and Linting, and Formatting (oh my!) + +We use nose2, flake8, and yapf to test, lint, and format code. You can use the `pytest` and `pyformat` subcommands to run these tests: + +### Testing and Linting + + qmk pytest + +### Formatting + + qmk pyformat + +## Formatting Details + +We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`. + +?> Tip- Many editors can use yapf as a plugin to automatically format code as you type. + +## Testing Details + +Our tests can be found in `lib/python/qmk/tests/`. You will find both unit and integration tests in this directory. We hope you will write both unit and integration tests for your code, but if you do not please favor integration tests. + +If your PR does not include a comprehensive set of tests please add comments like this to your code so that other people know where they can help: + + # TODO(unassigned/): Write tests + +We use [nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) to run our tests. You can refer to the nose2 documentation for more details on what you can do in your test functions. + +## Linting Details + +We use flake8 to lint our code. Your code should pass flake8 before you open a PR. This will be checked when you run `qmk pytest` and by CI when you submit a PR. diff --git a/coding_conventions_c.md b/coding_conventions_c.md new file mode 100644 index 00000000000..f4e359611b7 --- /dev/null +++ b/coding_conventions_c.md @@ -0,0 +1,58 @@ +# Coding Conventions (C) + +Most of our style is pretty easy to pick up on, but right now it's not entirely consistent. You should match the style of the code surrounding your change, but if that code is inconsistent or unclear use the following guidelines: + +* We indent using four (4) spaces (soft tabs) +* We use a modified One True Brace Style + * Opening Brace: At the end of the same line as the statement that opens the block + * Closing Brace: Lined up with the first character of the statement that opens the block + * Else If: Place the closing brace at the beginning of the line and the next opening brace at the end of the same line. + * Optional Braces: Always include optional braces. + * Good: if (condition) { return false; } + * Bad: if (condition) return false; +* We encourage use of C style comments: `/* */` + * Think of them as a story describing the feature + * Use them liberally to explain why particular decisions were made. + * Do not write obvious comments + * If you're not sure if a comment is obvious, go ahead and include it. +* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns. +* We use `#pragma once` at the start of header files rather than old-style include guards (`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`) +* We accept both forms of preprocessor if's: `#ifdef DEFINED` and `#if defined(DEFINED)` + * If you are not sure which to prefer use the `#if defined(DEFINED)` form. + * Do not change existing code from one style to the other, except when moving to a multiple condition `#if`. +* When deciding how (or if) to indent preprocessor directives, keep these points in mind: + * Readability is more important than consistency. + * Follow the file's existing style. If the file is mixed, follow the style that makes sense for the section you are modifying. + * When indenting, keep the hash at the start of the line and add whitespace between `#` and `if`, starting with 4 spaces after the `#`. + * You can follow the indention level of the surrounding C code, or preprocessor directives can have their own indentation levels. Choose the style that best communicates the intent of your code. + +Here is an example for easy reference: + +```c +/* Enums for foo */ +enum foo_state { + FOO_BAR, + FOO_BAZ, +}; + +/* Returns a value */ +int foo(void) { + if (some_condition) { + return FOO_BAR; + } else { + return -1; + } +} +``` + +# Auto-formatting with clang-format + +[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) is part of LLVM and can automatically format your code for you, because ain't nobody got time to do it manually. We supply a configuration file for it that applies most of the coding conventions listed above. It will only change whitespace and newlines, so you will still have to remember to include optional braces yourself. + +Use the [full LLVM installer](http://llvm.org/builds/) to get clang-format on Windows, or use `sudo apt install clang-format` on Ubuntu. + +If you run it from the command-line, pass `-style=file` as an option and it will automatically find the .clang-format configuration file in the QMK root directory. + +If you use VSCode, the standard C/C++ plugin supports clang-format, alternatively there is a [separate extension](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat) for it. + +Some things (like LAYOUT macros) are destroyed by clang-format, so either don't run it on those files, or wrap the sensitive code in `// clang-format off` and `// clang-format on`. diff --git a/coding_conventions_python.md b/coding_conventions_python.md new file mode 100644 index 00000000000..47dff7f8eea --- /dev/null +++ b/coding_conventions_python.md @@ -0,0 +1,326 @@ +# Coding Conventions (Python) + +Most of our style follows PEP8 with some local modifications to make things less nit-picky. + +* We target Python 3.6 for compatability with all supported platforms. +* We indent using four (4) spaces (soft tabs) +* We encourage liberal use of comments + * Think of them as a story describing the feature + * Use them liberally to explain why particular decisions were made. + * Do not write obvious comments + * If you're not sure if a comment is obvious, go ahead and include it. +* We require useful docstrings for all functions. +* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns. +* Some of our practices conflict with the wider python community to make our codebase more approachable to non-pythonistas. + +# YAPF + +You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](setup.cfg). + +# Imports + +We don't have a hard and fast rule for when to use `import ...` vs `from ... import ...`. Understandability and maintainability is our ultimate goal. + +Generally we prefer to import specific function and class names from a module to keep code shorter and easier to understand. Sometimes this results in a name that is ambiguous, and in such cases we prefer to import the module instead. You should avoid using the "as" keyword when importing, unless you are importing a compatability module. + +Imports should be one line per module. We group import statements together using the standard python rules- system, 3rd party, local. + +Do not use `from foo import *`. Supply a list of objects you want to import instead, or import the whole module. + +## Import Examples + +Good: + +``` +from qmk import effects + +effects.echo() +``` + +Bad: + +``` +from qmk.effects import echo + +echo() # It's unclear where echo comes from +``` + +Good: + +``` +from qmk.keymap import compile_firmware + +compile_firmware() +``` + +OK, but the above is better: + +``` +import qmk.keymap + +qmk.keymap.compile_firmware() +``` + +# Statements + +One statement per line. + +Even when allowed (EG `if foo: bar`) we do not combine 2 statements onto a single line. + +# Naming + +`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`, `function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`, `function_parameter_name`, `local_var_name`. + +Function names, variable names, and filenames should be descriptive; eschew abbreviation. In particular, do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word. + +Always use a .py filename extension. Never use dashes. + +## Names to Avoid + +* single character names except for counters or iterators. You may use `e` as an exception identifier in try/except statements. +* dashes (`-`) in any package/module name +* `__double_leading_and_trailing_underscore__` names (reserved by Python) + +# Docstrings + +To maintain consistency with our docstrings we've set out the following guidelines. + +* Use markdown formatting +* Always use triple-dquote docstrings with at least one linebreak: `"""\n"""` +* First line is a short (< 70 char) description of what the function does +* If you need more in your docstring leave a blank line between the description and the rest. +* Start indented lines at the same indent level as the opening triple-dquote +* Document all function arguments using the format described below +* If present, Args:, Returns:, and Raises: should be the last three things in the docstring, separated by a blank line each. + +## Simple docstring example + +``` +def my_awesome_function(): + """Return the number of seconds since 1970 Jan 1 00:00 UTC. + """ + return int(time.time()) +``` + +## Complex docstring example + +``` +def my_awesome_function(): + """Return the number of seconds since 1970 Jan 1 00:00 UTC. + + This function always returns an integer number of seconds. + """ + return int(time.time()) +``` + +## Function arguments docstring example + +``` +def my_awesome_function(start=None, offset=0): + """Return the number of seconds since 1970 Jan 1 00:00 UTC. + + This function always returns an integer number of seconds. + + + Args: + start + The time to start at instead of 1970 Jan 1 00:00 UTC + + offset + Return an answer that has this number of seconds subtracted first + + Returns: + An integer describing a number of seconds. + + Raises: + ValueError + When `start` or `offset` are not positive numbers + """ + if start < 0 or offset < 0: + raise ValueError('start and offset must be positive numbers.') + + if not start: + start = time.time() + + return int(start - offset) +``` + +# Exceptions + +Exceptions are used to handle exceptional situations. They should not be used for flow control. This is a break from the python norm of "ask for forgiveness." If you are catching an exception it should be to handle a situation that is unusual. + +If you use a catch-all exception for any reason you must log the exception and stacktrace using cli.log. + +Make your try/except blocks as short as possible. If you need a lot of try statements you may need to restructure your code. + +# Tuples + +When defining one-item tuples always include a trailing comma so that it is obvious you are using a tuple. Do not rely on implicit one-item tuple unpacking. Better still use a list which is unambiguous. + +This is particularly important when using the printf-style format strings that are commonly used. + +# Lists and Dictionaries + +We have configured YAPF to differentiate between sequence styles with a trailing comma. When a trailing comma is omitted YAPF will format the sequence as a single line. When a trailing comma is included YAPF will format the sequence with one item per line. + +You should generally prefer to keep short definition on a single line. Break out to multiple lines sooner rather than later to aid readability and maintainability. + +# Parentheses + +Avoid excessive parentheses, but do use parentheses to make code easier to understand. Do not use them in return statements unless you are explicitly returning a tuple, or it is part of a math expression. + +# Format Strings + +We generally prefer printf-style format strings. Example: + +``` +name = 'World' +print('Hello, %s!' % (name,)) +``` + +This style is used by the logging module, which we make use of extensively, and we have adopted it in other places for consistency. It is also more familiar to C programmers, who are a big part of our casual audience. + +Our included CLI module has support for using these without using the percent (%) operator. Look at `cli.echo()` and the various `cli.log` functions (EG, `cli.log.info()`) for more details. + +# Comprehensions & Generator Expressions + +We encourage the liberal use of comprehensions and generators, but do not let them get too complex. If you need complexity fall back to a for loop that is easier to understand. + +# Lambdas + +OK to use but probably should be avoided. With comprehensions and generators the need for lambdas is not as strong as it once was. + +# Conditional Expressions + +OK in variable assignment, but otherwise should be avoided. + +Conditional expressions are if statements that are in line with code. For example: + +``` +x = 1 if cond else 2 +``` + +It's generally not a good idea to use these as function arguments, sequence items, etc. It's too easy to overlook. + +# Default Argument Values + +Encouraged, but values must be immutable objects. + +When specifying default values in argument lists always be careful to specify objects that can't be modified in place. If you use a mutable object the changes you make will persist between calls, which is usually not what you want. Even if that is what you intend to do it is confusing for others and will hinder understanding. + +Bad: + +``` +def my_func(foo={}): + pass +``` + +Good: + +``` +def my_func(foo=None): + if not foo: + foo = {} +``` + +# Properties + +Always use properties instead of getter and setter functions. + +``` +class Foo(object): + def __init__(self): + self._bar = None + + @property + def bar(self): + return self._bar + + @bar.setter + def bar(self, bar): + self._bar = bar +``` + +# True/False Evaluations + +You should generally prefer the implicit True/False evaluation in if statements, rather than checking equivalency. + +Bad: + +``` +if foo == True: + pass + +if bar == False: + pass +``` + +Good: + +``` +if foo: + pass + +if not bar: + pass +``` + +# Decorators + +Use when appropriate. Try to avoid too much magic unless it helps with understanding. + +# Threading and Multiprocessing + +Should be avoided. If you need this you will have to make a strong case before we merge your code. + +# Power Features + +Python is an extremely flexible language and gives you many fancy features such as custom metaclasses, access to bytecode, on-the-fly compilation, dynamic inheritance, object reparenting, import hacks, reflection, modification of system internals, etc. + +Don't use these. + +Performance is not a critical concern for us, and code understandability is. We want our codebase to be approachable by someone who only has a day or two to play with it. These features generally come with a cost to easy understanding, and we would prefer to have code that can be readily understood over faster or more compact code. + +Note that some standard library modules use these techniques and it is ok to make use of those modules. But please keep readability and understandability in mind when using them. + +# Type Annotated Code + +For now we are not using any type annotation system, and would prefer that code remain unannotated. We may revisit this in the future. + +# Function length + +Prefer small and focused functions. + +We recognize that long functions are sometimes appropriate, so no hard limit is placed on function length. If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program. + +Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code. + +You could find long and complicated functions when working with some code. Do not be intimidated by modifying existing code: if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several different contexts, consider breaking up the function into smaller and more manageable pieces. + +# FIXMEs + +It is OK to leave FIXMEs in code. Why? Encouraging people to at least document parts of code that need to be thought out more (or that are confusing) is better than leaving this code undocumented. + +All FIXMEs should be formatted like: + +``` +FIXME(username): Revisit this code when the frob feature is done. +``` + +...where username is your GitHub username. + +# Testing + +We use a combination of Integration and Unit testing to ensure that the our code is as bug-free as possible. All the tests can be found in `lib/python/qmk/tests/`. You can run all the tests with `qmk pytest`. + +At the time of this writing our tests are not very comprehensive. Looking at the current tests and writing new test cases for untested situations is a great way to both familiarize yourself with the codebase and contribute to QMK. + +## Integration Tests + +Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened. + +## Unit Tests + +The other `test_*.py` files in `lib/python/qmk/tests/` contain unit tests. You can write tests for individual functions inside `lib/python/qmk/` here. Generally these files are named after the module, with dots replaced by underscores. + +At the time of this writing we do not do any mocking for our tests. If you would like to help us change this please [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and start a conversation there. diff --git a/compatible_microcontrollers.md b/compatible_microcontrollers.md new file mode 100644 index 00000000000..ac90ed7464f --- /dev/null +++ b/compatible_microcontrollers.md @@ -0,0 +1,37 @@ +# Compatible Microcontrollers + +QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB or more, though it will *just* squeeze into 16kB with most features disabled. + +## Atmel AVR + +The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB stack: + +* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) +* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) +* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) + +Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead: + +* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) +* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) +* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328) + +## ARM + +You can also use any ARM chip with USB that [ChibiOS](http://www.chibios.org) supports. Most have plenty of flash. Known to work are: + +### STMicroelectronics (STM32) + + * [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html) + * [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html) + * [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html) + +### NXP (Kinetis) + + * [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) + * [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50) + * [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72) + +## Atmel ATSAM + +There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). diff --git a/config_options.md b/config_options.md new file mode 100644 index 00000000000..f9b1cc65787 --- /dev/null +++ b/config_options.md @@ -0,0 +1,414 @@ +# Configuring QMK + +QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however. + +There are two main types of configuration files in QMK- `config.h` and `rules.mk`. These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are: + +* QMK Default +* Keyboard +* Folders (Up to 5 levels deep) +* Keymap + +## QMK Default + +Every available setting in QMK has a default. If that setting is not set at the Keyboard, Folder, or Keymap level this is the setting that will be used. + +## Keyboard + +This level contains config options that should apply to the whole keyboard. Some settings won't change in revisions, or most keymaps. Other settings are merely defaults for this keyboard and can be overridden by folders and/or keymaps. + +## Folders + +Some keyboards have folders and sub-folders to allow for different hardware configurations. Most keyboards only go 1 folder deep, but QMK supports structures up to 5 folders deep. Each folder can have its own `config.h` and `rules.mk` files that are incorporated into the final configuration. + +## Keymap + +This level contains all of the options for that particular keymap. If you wish to override a previous declaration, you can use `#undef ` to undefine it, where you can then redefine it without an error. + +# The `config.h` File + +This is a C header file that is one of the first things included, and will persist over the whole project (if included). Lots of variables can be set here and accessed elsewhere. The `config.h` file shouldn't be including other `config.h` files, or anything besides this: + + #include "config_common.h" + + +## Hardware Options +* `#define VENDOR_ID 0x1234` + * defines your VID, and for most DIY projects, can be whatever you want +* `#define PRODUCT_ID 0x5678` + * defines your PID, and for most DIY projects, can be whatever you want +* `#define DEVICE_VER 0` + * defines the device version (often used for revisions) +* `#define MANUFACTURER Me` + * generally who/whatever brand produced the board +* `#define PRODUCT Board` + * the name of the keyboard +* `#define MATRIX_ROWS 5` + * the number of rows in your keyboard's matrix +* `#define MATRIX_COLS 15` + * the number of columns in your keyboard's matrix +* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }` + * pins of the rows, from top to bottom +* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }` + * pins of the columns, from left to right +* `#define MATRIX_IO_DELAY 30` + * the delay in microseconds when between changing matrix pin state and reading values +* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }` + * pins unused by the keyboard for reference +* `#define MATRIX_HAS_GHOST` + * define is matrix has ghost (unlikely) +* `#define DIODE_DIRECTION COL2ROW` + * COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows. +* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` + * pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground. +* `#define AUDIO_VOICES` + * turns on the alternate audio voices (to cycle through) +* `#define C4_AUDIO` + * enables audio on pin C4 +* `#define C5_AUDIO` + * enables audio on pin C5 +* `#define C6_AUDIO` + * enables audio on pin C6 +* `#define B5_AUDIO` + * enables audio on pin B5 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) +* `#define B6_AUDIO` + * enables audio on pin B6 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) +* `#define B7_AUDIO` + * enables audio on pin B7 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) +* `#define BACKLIGHT_PIN B7` + * pin of the backlight +* `#define BACKLIGHT_LEVELS 3` + * number of levels your backlight will have (maximum 31 excluding off) +* `#define BACKLIGHT_BREATHING` + * enables backlight breathing +* `#define BREATHING_PERIOD 6` + * the length of one backlight "breath" in seconds +* `#define DEBOUNCE 5` + * the delay when reading the value of the pin (5 is default) +* `#define LOCKING_SUPPORT_ENABLE` + * mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap +* `#define LOCKING_RESYNC_ENABLE` + * tries to keep switch state consistent with keyboard LED state +* `#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)` + * key combination that allows the use of magic commands (useful for debugging) +* `#define USB_MAX_POWER_CONSUMPTION 500` + * sets the maximum power (in mA) over USB for the device (default: 500) +* `#define USB_POLLING_INTERVAL_MS 10` + * sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces +* `#define F_SCL 100000L` + * sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`. + +## Features That Can Be Disabled + +If you define these options you will disable the associated feature, which can save on code size. + +* `#define NO_DEBUG` + * disable debugging +* `#define NO_PRINT` + * disable printing/debugging using hid_listen +* `#define NO_ACTION_LAYER` + * disable layers +* `#define NO_ACTION_TAPPING` + * disable tap dance and other tapping features +* `#define NO_ACTION_ONESHOT` + * disable one-shot modifiers +* `#define NO_ACTION_MACRO` + * disable old-style macro handling using `MACRO()`, `action_get_macro()` _(deprecated)_ +* `#define NO_ACTION_FUNCTION` + * disable old-style function handling using `fn_actions`, `action_function()` _(deprecated)_ + +## Features That Can Be Enabled + +If you define these options you will enable the associated feature, which may increase your code size. + +* `#define FORCE_NKRO` + * NKRO by default requires to be turned on, this forces it on during keyboard startup regardless of EEPROM setting. NKRO can still be turned off but will be turned on again if the keyboard reboots. +* `#define STRICT_LAYER_RELEASE` + * force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases) + +## Behaviors That Can Be Configured + +* `#define TAPPING_TERM 200` + * how long before a tap becomes a hold, if set above 500, a key tapped during the tapping term will turn it into a hold too +* `#define TAPPING_TERM_PER_KEY` + * enables handling for per key `TAPPING_TERM` settings +* `#define RETRO_TAPPING` + * tap anyway, even after TAPPING_TERM, if there was no other key interruption between press and release + * See [Retro Tapping](tap_hold.md#retro-tapping) for details +* `#define TAPPING_TOGGLE 2` + * how many taps before triggering the toggle +* `#define PERMISSIVE_HOLD` + * makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM` + * See [Permissive Hold](tap_hold.md#permissive-hold) for details +* `#define PERMISSIVE_HOLD_PER_KEY` + * enabled handling for per key `PERMISSIVE_HOLD` settings +* `#define IGNORE_MOD_TAP_INTERRUPT` + * makes it possible to do rolling combos (zx) with keys that convert to other keys on hold, by enforcing the `TAPPING_TERM` for both keys. + * See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details +* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY` + * enables handling for per key `IGNORE_MOD_TAP_INTERRUPT` settings +* `#define TAPPING_FORCE_HOLD` + * makes it possible to use a dual role key as modifier shortly after having been tapped + * See [Tapping Force Hold](tap_hold.md#tapping-force-hold) + * Breaks any Tap Toggle functionality (`TT` or the One Shot Tap Toggle) +* `#define TAPPING_FORCE_HOLD_PER_KEY` + * enables handling for per key `TAPPING_FORCE_HOLD` settings +* `#define LEADER_TIMEOUT 300` + * how long before the leader key times out + * If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped. +* `#define LEADER_PER_KEY_TIMING` + * sets the timer for leader key chords to run on each key press rather than overall +* `#define LEADER_KEY_STRICT_KEY_PROCESSING` + * Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`. +* `#define ONESHOT_TIMEOUT 300` + * how long before oneshot times out +* `#define ONESHOT_TAP_TOGGLE 2` + * how many taps before oneshot toggle is triggered +* `#define QMK_KEYS_PER_SCAN 4` + * Allows sending more than one key per scan. By default, only one key event gets + sent via `process_record()` per scan. This has little impact on most typing, but + if you're doing a lot of chords, or your scan rate is slow to begin with, you can + have some delay in processing key events. Each press and release is a separate + event. For a keyboard with 1ms or so scan times, even a very fast typist isn't + going to produce the 500 keystrokes a second needed to actually get more than a + few ms of delay from this. But if you're doing chording on something with 3-4ms + scan times? You probably want this. +* `#define COMBO_COUNT 2` + * Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature. +* `#define COMBO_TERM 200` + * how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined. +* `#define TAP_CODE_DELAY 100` + * Sets the delay between `register_code` and `unregister_code`, if you're having issues with it registering properly (common on VUSB boards). The value is in milliseconds. +* `#define TAP_HOLD_CAPS_DELAY 80` + * Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPSLOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher. + +## RGB Light Configuration + +* `#define RGB_DI_PIN D7` + * pin the DI on the WS2812 is hooked-up to +* `#define RGBLIGHT_ANIMATIONS` + * run RGB animations +* `#define RGBLIGHT_LAYERS` + * Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state. +* `#define RGBLIGHT_MAX_LAYERS` + * Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight.md?id=lighting-layers) are needed. + * Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards. +* `#define RGBLIGHT_LAYER_BLINK` + * Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action). +* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` + * If defined, then [lighting layers](feature_rgblight?id=overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off. +* `#define RGBLED_NUM 12` + * number of LEDs +* `#define RGBLIGHT_SPLIT` + * Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half +* `#define RGBLED_SPLIT { 6, 6 }` + * number of LEDs connected that are directly wired to `RGB_DI_PIN` on each half of a split keyboard + * First value indicates number of LEDs for left half, second value is for the right half + * When RGBLED_SPLIT is defined, RGBLIGHT_SPLIT is implicitly defined. +* `#define RGBLIGHT_HUE_STEP 12` + * units to step when in/decreasing hue +* `#define RGBLIGHT_SAT_STEP 25` + * units to step when in/decreasing saturation +* `#define RGBLIGHT_VAL_STEP 12` + * units to step when in/decreasing value (brightness) +* `#define RGBW` + * Enables RGBW LED support + +## Mouse Key Options + +* `#define MOUSEKEY_INTERVAL 20` +* `#define MOUSEKEY_DELAY 0` +* `#define MOUSEKEY_TIME_TO_MAX 60` +* `#define MOUSEKEY_MAX_SPEED 7` +* `#define MOUSEKEY_WHEEL_DELAY 0` + +## Split Keyboard Options + +Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk + +* `SPLIT_TRANSPORT = custom` + * Allows replacing the standard split communication routines with a custom one. ARM based split keyboards must use this at present. + +### Setting Handedness + +One thing to remember, the side that the USB port is plugged into is always the master half. The side not plugged into USB is the slave. + +There are a few different ways to set handedness for split keyboards (listed in order of precedence): + +1. Set `SPLIT_HAND_PIN`: Reads a pin to determine handedness. If pin is high, it's the left side, if low, the half is determined to be the right side +2. Set `EE_HANDS` and flash `eeprom-lefthand.eep`/`eeprom-righthand.eep` to each half + * For boards with DFU bootloader you can use `:dfu-split-left`/`:dfu-split-right` to flash these EEPROM files + * For boards with Caterina bootloader (like stock Pro Micros), use `:avrdude-split-left`/`:avrdude-split-right` + * For boards with ARM DFU bootloader (like Proton C), use `:dfu-util-split-left`/`:dfu-util-split-right` +3. Set `MASTER_RIGHT`: Half that is plugged into the USB port is determined to be the master and right half (inverse of the default) +4. Default: The side that is plugged into the USB port is the master half and is assumed to be the left half. The slave side is the right half + +#### Defines for handedness + +* `#define SPLIT_HAND_PIN B7` + * For using high/low pin to determine handedness, low = right hand, high = left hand. Replace `B7` with the pin you are using. This is optional, and if you leave `SPLIT_HAND_PIN` undefined, then you can still use the EE_HANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses. + +* `#define SPLIT_HAND_MATRIX_GRID ,` + * The handedness is determined by using the intersection of the keyswitches in the key matrix, which does not exist. Normally, when this intersection is shorted (level low), it is considered left. If you define `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT`, it is determined to be right when the level is low. + +* `#define EE_HANDS` (only works if `SPLIT_HAND_PIN` and `SPLIT_HAND_MATRIX_GRID` are not defined) + * Reads the handedness value stored in the EEPROM after `eeprom-lefthand.eep`/`eeprom-righthand.eep` has been flashed to their respective halves. + +* `#define MASTER_RIGHT` + * Master half is defined to be the right half. + +### Other Options + +* `#define USE_I2C` + * For using I2C instead of Serial (defaults to serial) + +* `#define SOFT_SERIAL_PIN D0` + * When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`. + +* `#define MATRIX_ROW_PINS_RIGHT { }` +* `#define MATRIX_COL_PINS_RIGHT { }` + * If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns. + +* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` + * If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`. + +* `#define RGBLED_SPLIT { 6, 6 }` + * See [RGB Light Configuration](#rgb-light-configuration) + +* `#define SELECT_SOFT_SERIAL_SPEED ` (default speed is 1) + * Sets the protocol speed when using serial communication + * Speeds: + * 0: about 189kbps (Experimental only) + * 1: about 137kbps (default) + * 2: about 75kbps + * 3: about 39kbps + * 4: about 26kbps + * 5: about 20kbps + +* `#define SPLIT_USB_DETECT` + * Detect (with timeout) USB connection when delegating master/slave + * Default behavior for ARM + * Required for AVR Teensy + +* `#define SPLIT_USB_TIMEOUT 2000` + * Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT` + +* `#define SPLIT_USB_TIMEOUT_POLL 10` + * Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT` + +# The `rules.mk` File + +This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features. + +## Build Options + +* `DEFAULT_FOLDER` + * Used to specify a default folder when a keyboard has more than one sub-folder. +* `FIRMWARE_FORMAT` + * Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building. +* `SRC` + * Used to add files to the compilation/linking list. +* `LIB_SRC` + * Used to add files as a library to the compilation/linking list. + The files specified by `LIB_SRC` is linked after the files specified by `SRC`. + For example, if you specify: + ``` + SRC += a.c + LIB_SRC += lib_b.c + SRC += c.c + LIB_SRC += lib_d.c + ``` + The link order is as follows. + ``` + ... a.o c.o ... lib_b.a lib_d.a ... + ``` +* `LAYOUTS` + * A list of [layouts](feature_layouts.md) this keyboard supports. +* `LTO_ENABLE` + * Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). +However, this will automatically disable the legacy TMK Macros and Functions features, as these break when LTO is enabled. It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`. (Note: This does not affect QMK [Macros](feature_macros.md) and [Layers](feature_layers.md).) + +## AVR MCU Options +* `MCU = atmega32u4` +* `F_CPU = 16000000` +* `ARCH = AVR8` +* `F_USB = $(F_CPU)` +* `OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT` +* `BOOTLOADER = atmel-dfu` with the following options: + * `atmel-dfu` + * `lufa-dfu` + * `qmk-dfu` + * `halfkay` + * `caterina` + * `bootloadHID` + * `USBasp` + +## Feature Options :id=feature-options + +Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU. + +* `BOOTMAGIC_ENABLE` + * Virtual DIP switch configuration +* `MOUSEKEY_ENABLE` + * Mouse keys +* `EXTRAKEY_ENABLE` + * Audio control and System control +* `CONSOLE_ENABLE` + * Console for debug +* `COMMAND_ENABLE` + * Commands for debug and configuration +* `COMBO_ENABLE` + * Key combo feature +* `NKRO_ENABLE` + * USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +* `AUDIO_ENABLE` + * Enable the audio subsystem. +* `RGBLIGHT_ENABLE` + * Enable keyboard underlight functionality +* `LEADER_ENABLE` + * Enable leader key chording +* `MIDI_ENABLE` + * MIDI controls +* `UNICODE_ENABLE` + * Unicode +* `BLUETOOTH` + * Current options are AdafruitBLE, RN42 +* `SPLIT_KEYBOARD` + * Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common +* `CUSTOM_MATRIX` + * Allows replacing the standard matrix scanning routine with a custom one. +* `DEBOUNCE_TYPE` + * Allows replacing the standard key debouncing routine with an alternative or custom one. +* `WAIT_FOR_USB` + * Forces the keyboard to wait for a USB connection to be established before it starts up +* `NO_USB_STARTUP_CHECK` + * Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master. + +## USB Endpoint Limitations + +In order to provide services over USB, QMK has to use USB endpoints. +These are a finite resource: each microcontroller has only a certain number. +This limits what features can be enabled together. +If the available endpoints are exceeded, a build error is thrown. + +The following features can require separate endpoints: + +* `MOUSEKEY_ENABLE` +* `EXTRAKEY_ENABLE` +* `CONSOLE_ENABLE` +* `NKRO_ENABLE` +* `MIDI_ENABLE` +* `RAW_ENABLE` +* `VIRTSER_ENABLE` + +In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint. +By default, `MOUSEKEY`, `EXTRAKEY`, and `NKRO` are combined into a single endpoint. + +The base keyboard functionality can also be combined into the endpoint, +by setting `KEYBOARD_SHARED_EP = yes`. +This frees up one more endpoint, +but it can prevent the keyboard working in some BIOSes, +as they do not implement Boot Keyboard protocol switching. + +Combining the mouse also breaks Boot Mouse compatibility. +The mouse can be uncombined by setting `MOUSE_SHARED_EP = no` if this functionality is required. diff --git a/configurator_default_keymaps.md b/configurator_default_keymaps.md new file mode 100644 index 00000000000..30f9fa72f32 --- /dev/null +++ b/configurator_default_keymaps.md @@ -0,0 +1,193 @@ +# Adding Default Keymaps to QMK Configurator :id=adding-default-keymaps + +This page covers how to add a default keymap for a keyboard to QMK Configurator. + + +## Technical Information :id=technical-information + +QMK Configurator uses JSON as its native file format for keymaps. As much as possible, these should be kept such that they behave the same as running `make :default` from `qmk_firmware`. + +Keymaps in this directory require four key-value pairs: + +* `keyboard` (string) + * This is the name of the keyboard, the same as would be used when running a compile job through `make` (e.g. `make 1upkeyboards/1up60rgb:default`). +* `keymap` (string) + * Should be set to `default`. +* `layout` (string) + * This is the layout macro used by the default keymap. +* `layers` (array) + * The keymap itself. This key should contain one array per layer, which themselves should contain the keycodes that make up that layer. + +Additionally, most keymaps contain a `commit` key. This key is not consumed by the API that back-stops QMK Configurator, but is used by Configurator's maintainers to tell which version of a keymap was used to create the JSON keymap in this repository. The value is the SHA of the last commit to modify a board's default `keymap.c` in the `qmk_firmware` repository. The SHA is found by checking out [the `master` branch of the `qmk/qmk_firmware` repository](https://github.com/qmk/qmk_firmware/tree/master/) and running `git log -1 --pretty=oneline -- keyboards//keymaps/default/keymap.c` (use `keymap.json` if the keyboard in question has this file instead), which should return something similar to: + +```shell +f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from default keymaps (#5625) +``` + +In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`. + + +## Example :id=example + +If one wished to add a default keymap for the H87a by Hineybush, one would run the `git log` command above against the H87a's default keymap in `qmk_firmware`: + +```shell +user ~/qmk_firmware (master) +$ git log -1 --pretty=oneline master -- keyboards/hineybush/h87a/keymaps/default/keymap.c +ef8878fba5d3786e3f9c66436da63a560cd36ac9 Hineybush h87a lock indicators (#8237) +``` + +Now that we have the commit hash, we need the keymap (edited for readability): + +```c +... +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT_all( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, + KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_TRNS, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [1] = LAYOUT_all( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DEC, BL_INC, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), + +}; +``` + +The default keymap uses the `LAYOUT_all` macro, so that will be the value of the `layout` key. Compiled to a QMK Configurator JSON keymap, our resulting file should be: + +```json +{ + "keyboard": "hineybush/h87a", + "keymap": "default", + "commit": "ef8878fba5d3786e3f9c66436da63a560cd36ac9", + "layout": "LAYOUT_all", + "layers": [ + [ + "KC_ESC", "KC_F1", "KC_F2", "KC_F3", "KC_F4", "KC_F5", "KC_F6", "KC_F7", "KC_F8", "KC_F9", "KC_F10", "KC_F11", "KC_F12", "KC_PSCR", "KC_SLCK", "KC_PAUS", + "KC_GRV", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", "KC_MINS", "KC_EQL", "KC_BSPC", "KC_BSPC", "KC_INS", "KC_HOME", "KC_PGUP", + "KC_TAB", "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P", "KC_LBRC", "KC_RBRC", "KC_BSLS", "KC_DEL", "KC_END", "KC_PGDN", + "KC_CAPS", "KC_A", "KC_S", "KC_D", "KC_F", "KC_G", "KC_H", "KC_J", "KC_K", "KC_L", "KC_SCLN", "KC_QUOT", "KC_NUHS", "KC_ENT", + "KC_LSFT", "KC_NUBS", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", "KC_RSFT", "KC_TRNS", "KC_UP", + "KC_LCTL", "KC_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "MO(1)", "KC_RGUI", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RGHT" + ], + [ + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DEC", "BL_INC", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RESET", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS" + ] + ] +} +``` + +The white space in the `layers` arrays have no effect on the functionality of the keymap, but are used to make these files easier for humans to read. + + +## Caveats :id=caveats + +### Layers can only be referenced by number :id=layer-references + +A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement: + +```c +enum layer_names { + _BASE, + _MEDIA, + _FN +}; +``` + +This works in C, but for Configurator, you *must* use the layer's numeric index – `MO(_FN)` would need to be `MO(2)` in the above example. + +### No support for custom code of any kind :id=custom-code + +Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can not be compiled in Configurator **at all**. Even setting `TAP_DANCE_ENABLE = yes` in the `qmk_firmware` repository at the keyboard level will prevent Configurator from compiling **any** firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format. + +### Limited Support for Custom keycodes :id=custom-keycodes + +There is a way to support custom keycodes: if the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode *can* be used in Configurator and it *will* compile and work. Instead of using the following in your `keymap.c`: + +```c +enum custom_keycodes { + MACRO_1 = SAFE_RANGE, + MACRO_2, + MACRO_3 +}; +... +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case MACRO_1: + if (record->event.pressed) { + SEND_STRING("This is macro #1."); + } + return false; + case MACRO_2: + if (record->event.pressed) { + SEND_STRING("This is macro #2."); + } + return false; + case MACRO_3: + if (record->event.pressed) { + SEND_STRING("This is macro #3."); + } + return false; + } + return true; +}; +``` + +... add the keycode `enum` block to your keyboard's header file (`.h`) as follows (note that the `enum` is named `keyboard_keycodes` here): + +```c +enum keyboard_keycodes { + MACRO_1 = SAFE_RANGE, + MACRO_2, + MACRO_3, + NEW_SAFE_RANGE // Important! +}; +``` + +... then the logic to your `.c` through `process_record_kb()`: + +```c +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case MACRO_1: + if (record->event.pressed) { + SEND_STRING("This is macro #1."); + } + return false; + case MACRO_2: + if (record->event.pressed) { + SEND_STRING("This is macro #2."); + } + return false; + case MACRO_3: + if (record->event.pressed) { + SEND_STRING("This is macro #3."); + } + return false; + } + return process_record_user(keycode, record); +}; +``` + +Note the call to `process_record_user()` at the end. Additionally, users of the keyboard will need to use `NEW_SAFE_RANGE` instead of `SAFE_RANGE` if they wish to add their own custom keycodes at keymap level, beyond what is provided by the keyboard. + + +## Additional Reading :id=additional-reading + +For QMK Configurator to support your keyboard, your keyboard must be present in the `master` branch of the `qmk_firmware` repository. For instructions on this, please see [Supporting Your Keyboard in QMK Configurator](reference_configurator_support.md). diff --git a/configurator_step_by_step.md b/configurator_step_by_step.md new file mode 100644 index 00000000000..965012a907e --- /dev/null +++ b/configurator_step_by_step.md @@ -0,0 +1,58 @@ +# QMK Configurator: Step by Step + +This page describes the steps for building your firmware in QMK Configurator. + +## Step 1: Select Your Keyboard + +Click the drop down box and select the keyboard you want to create a keymap for. + +?> If your keyboard has several versions, make sure you select the correct one. + +I'll say that again because it's important: + +!> **MAKE SURE YOU SELECT THE RIGHT VERSION!** + +If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. + +## Step 2: Select Your Keyboard Layout + +Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future. + +!> Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`. + +## Step 3: Name Your Keymap + +Call this keymap what you want. + +?> If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo. + +## Step 4: Define Your Keymap + +Keycode Entry is accomplished in one of 3 ways: + +1. Drag and drop +2. Clicking on an empty spot on the layout, then clicking the keycode you desire +3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard + +?> Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see: + +* [Basic Keycode Reference](keycodes_basic.md) +* [Advanced Keycode Reference](feature_advanced_keycodes.md) + +!> If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations. + +## Step 5: Save Your Keymap for Future Changes + +When you're satisfied with your keymap or just want to work on it later, press the `Export Keymap` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Import Keymap` button. + +!> **CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems. + +## Step 6: Compile Your Firmware File + +Press the green `Compile` button. + +When the compilation is done, you will be able to press the green `Download Firmware` button. + +## Next steps: Flashing Your Keyboard + +Please refer to [Flashing Firmware](newbs_flashing.md). diff --git a/configurator_troubleshooting.md b/configurator_troubleshooting.md new file mode 100644 index 00000000000..80b9713b64e --- /dev/null +++ b/configurator_troubleshooting.md @@ -0,0 +1,26 @@ +# Configurator Troubleshooting + +## My .json file is not working + +If the .json file was generated with QMK Configurator, congratulations you have stumbled upon a bug. File an issue at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues). + +If not... how did you miss the big bold message at the top saying not to use other .json files? + +## There are extra spaces in my layout? What do I do? + +If you're referring to having three spots for space bar, the best course of action is to just fill them all with Space. The same can be done for Backspace and Shift keys. + +## What is the keycode for... + +Please see: + +* [Basic Keycode Reference](keycodes_basic.md) +* [Advanced Keycode Reference](feature_advanced_keycodes.md) + +## It won't compile + +Please double check the other layers of your keymap to make sure there are no random keys present. + +## Problems and Bugs + +We are always accepting customer requests and bug reports. Please file them at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues). diff --git a/contributing.md b/contributing.md new file mode 100644 index 00000000000..f325566fd06 --- /dev/null +++ b/contributing.md @@ -0,0 +1,168 @@ +# How to Contribute + +👍🎉 First off, thanks for taking the time to read this and contribute! 🎉👍 + +Third-party contributions help us grow and improve QMK. We want to make the pull request and contribution process useful and easy for both contributors and maintainers. To this end we've put together some guidelines for contributors to help your pull request be accepted without major changes. + +* [Project Overview](#project-overview) +* [Coding Conventions](#coding-conventions) +* [General Guidelines](#general-guidelines) +* [What does the Code of Conduct mean for me?](#what-does-the-code-of-conduct-mean-for-me) + +## I Don't Want to Read This Whole Thing! I Just Have a Question! + +If you'd like to ask questions about QMK you can do so on the [OLKB Subreddit](https://reddit.com/r/olkb) or on [Discord](https://discord.gg/Uq7gcHh). + +Please keep these things in mind: + +* It may take several hours for someone to respond to your question. Please be patient! +* Everyone involved with QMK is donating their time and energy. We don't get paid to work on or answer questions about QMK. +* Try to ask your question so it's as easy to answer as possible. If you're not sure how to do that these are some good guides: + * https://opensource.com/life/16/10/how-ask-technical-questions + * http://www.catb.org/esr/faqs/smart-questions.html + +# Project Overview + +QMK is largely written in C, with specific features and parts written in C++. It targets embedded processors found in keyboards, particularly AVR ([LUFA](http://www.fourwalledcubicle.com/LUFA.php)) and ARM ([ChibiOS](http://www.chibios.com)). If you are already well versed in Arduino programming you'll find a lot of the concepts and limitations familiar. Prior experience with Arduino is not required to successfully contribute to QMK. + + + +# Where Can I Go for Help? + +If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/issues) or [chat on Discord](https://discord.gg/Uq7gcHh). + +# How Do I Make a Contribution? + +Never made an open source contribution before? Wondering how contributions work in QMK? Here's a quick rundown! + +0. Sign up for a [GitHub](https://github.com) account. +1. Put together a keymap to contribute, [find an issue](https://github.com/qmk/qmk_firmware/issues) you are interested in addressing, or [a feature](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) you would like to add. +2. Fork the repository associated with the issue to your GitHub account. This means that you will have a copy of the repository under `your-GitHub-username/qmk_firmware`. +3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`. +4. If you're working on a new feature consider opening an issue to talk with us about the work you're about to undertake. +5. Create a new branch for your fix using `git checkout -b branch-name-here`. +6. Make the appropriate changes for the issue you are trying to address or the feature that you want to add. +7. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index. +8. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message. +9. Push the changes to your repository on GitHub using `git push origin branch-name-here`. +10. Submit a pull request to [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master). +11. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so "Added more log outputting to resolve #4352". +12. In the description of the pull request explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it! +13. Wait for the pull request to be reviewed by a maintainer. +14. Make changes to the pull request if the reviewing maintainer recommends them. +15. Celebrate your success after your pull request is merged! + +# Coding Conventions + +Most of our style is pretty easy to pick up on. If you are familiar with either C or Python you should not have too much trouble with our local styles. + +* [Coding Conventions - C](coding_conventions_c.md) +* [Coding Conventions - Python](coding_conventions_python.md) + +# General Guidelines + +We have a few different types of changes in QMK, each requiring a different level of rigor. We'd like you to keep the following guidelines in mind no matter what type of change you're making. + +* Separate PRs into logical units. For example, do not submit one PR covering two separate features, instead submit a separate PR for each feature. +* Check for unnecessary whitespace with `git diff --check` before committing. +* Make sure your code change actually compiles. + * Keymaps: Make sure that `make keyboard:your_new_keymap` does not return any errors. + * Keyboards: Make sure that `make keyboard:all` does not return any errors. + * Core: Make sure that `make all` does not return any errors. +* Make sure commit messages are understandable on their own. You should put a short description (no more than 70 characters) on the first line, the second line should be empty, and on the 3rd and later lines you should describe your commit in detail, if required. Example: + +``` +Adjust the fronzlebop for the kerpleplork + +The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations. + +Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure. +``` + +!> **IMPORTANT:** If you would like to contribute a bugfix or improvement to user code, such as non-default keymaps, userspace and layouts, be sure to tag the original submitter of the code in your PR. Many users, regardless of skill level with Git and GitHub, may be confused or frustrated at their code being modified without their knowledge. + +## Documentation + +Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)! + +You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click the "Edit this page" link at the bottom of each page on https://docs.qmk.fm/. + +When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency: + +```c +enum my_layers { + _FIRST_LAYER, + _SECOND_LAYER +}; + +enum my_keycodes { + FIRST_LAYER = SAFE_RANGE, + SECOND_LAYER +}; +``` + +### Previewing the Documentation :id=previewing-the-documentation + +Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder: + + ./bin/qmk docs + +or if you only have Python 3 installed: + + python3 -m http.server 8936 + +and navigating to `http://localhost:8936/`. + +## Keymaps + +Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap. + +* Write a `readme.md` using [the template](documentation_templates.md). +* All Keymap PR's are squashed, so if you care about how your commits are squashed you should do it yourself +* Do not lump features in with keymap PR's. Submit the feature first and then a second PR for the keymap. +* Do not include `Makefile`s in your keymap folder (they're no longer used) +* Update copyrights in file headers (look for `%YOUR_NAME%`) + +## Keyboards + +Keyboards are the raison d'être for QMK. Some keyboards are community maintained, while others are maintained by the people responsible for making a particular keyboard. The `readme.md` should tell you who maintains a particular keyboard. If you have questions relating to a particular keyboard you can [Open An Issue](https://github.com/qmk/qmk_firmware/issues) and tag the maintainer in your question. + +We also ask that you follow these guidelines: + +* Write a `readme.md` using [the template](documentation_templates.md). +* Keep the number of commits reasonable or we will squash your PR +* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard. +* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards///.[ch]` +* Do not include `Makefile`s in your keyboard folder (they're no longer used) +* Update copyrights in file headers (look for `%YOUR_NAME%`) + +## Quantum/TMK Core + +Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk.md), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this: + +* [Chat on Discord](https://discord.gg/Uq7gcHh) +* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new) + +Feature and Bug Fix PR's affect all keyboards. We are also in the process of restructuring QMK. For this reason it is especially important for significant changes to be discussed before implementation has happened. If you open a PR without talking to us first please be prepared to do some significant rework if your choices do not mesh well with our planned direction. + +Here are some things to keep in mind when working on your feature or bug fix. + +* **Disabled by default** - memory is a pretty limited on most chips QMK supports, and it's important that current keymaps aren't broken, so please allow your feature to be turned **on**, rather than being turned off. If you think it should be on by default, or reduces the size of the code, please talk with us about it. +* **Compile locally before submitting** - hopefully this one is obvious, but things need to compile! Our Travis system will catch any issues, but it's generally faster for you to compile a few keyboards locally instead of waiting for the results to come back. +* **Consider revisions and different chip-bases** - there are several keyboards that have revisions that allow for slightly different configurations, and even different chip-bases. Try to make a feature supported in ARM and AVR, or automatically disabled on platforms it doesn't work on. +* **Explain your feature** - Document it in `docs/`, either as a new file or as part of an existing file. If you don't document it other people won't be able to benefit from your hard work. + +We also ask that you follow these guidelines: + +* Keep the number of commits reasonable or we will squash your PR +* Do not lump keyboards or keymaps in with core changes. Submit your core changes first. +* Write [Unit Tests](unit_testing.md) for your feature +* Follow the style of the file you are editing. If the style is unclear or there are mixed styles you should conform to the [coding conventions](#coding-conventions) above. + +## Refactoring + +To maintain a clear vision of how things are laid out in QMK we try to plan out refactors in-depth and have a collaborator make the changes. If you have an idea for refactoring, or suggestions, [open an issue](https://github.com/qmk/qmk_firmware/issues), we'd love to talk about how QMK can be improved. + +# What Does the Code of Conduct Mean for Me? + +Our [Code of Conduct](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md) means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code. diff --git a/custom_matrix.md b/custom_matrix.md new file mode 100644 index 00000000000..cfa900a33d3 --- /dev/null +++ b/custom_matrix.md @@ -0,0 +1,108 @@ +# Custom Matrix + +QMK provides a mechanism to supplement or replace the default matrix scanning routine with your own code. + +The reasons to use this feature include: + +* Extra hardware between the keyboard's switches and MCU pins + * I/O multiplexer + * Line decoder +* Irregular switch matrix + * Simultaneous use of `COL2ROW` and `ROW2COL` + +## Prerequisites + +Implementing custom matrix usually involves compilation of an additional source file. It is recommended that for consistency, this file is called `matrix.c`. + +Add a new file to your keyboard directory: +```text +keyboards//matrix.c +``` + +And to configure compilation for the new file, add this to your `rules.mk`: +```make +SRC += matrix.c +``` + +## 'lite' + +Provides a default implementation for various scanning functions, reducing the boilerplate code when implementing custom matrix. +To configure it, add this to your `rules.mk`: + +```make +CUSTOM_MATRIX = lite +``` + +And implement the following functions in a `matrix.c` file in your keyboard folder: + +```c +void matrix_init_custom(void) { + // TODO: initialize hardware here +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + bool matrix_has_changed = false; + + // TODO: add matrix scanning routine here + + return matrix_has_changed; +} +``` + + +## Full Replacement + +When more control over the scanning routine is required, you can choose to implement the full scanning routine. +To configure it, add this to your rules.mk: + +```make +CUSTOM_MATRIX = yes +``` + +And implement the following functions in a `matrix.c` file in your keyboard folder: + +```c +matrix_row_t matrix_get_row(uint8_t row) { + // TODO: return the requested row data +} + +void matrix_print(void) { + // TODO: use print() to dump the current matrix state to console +} + +void matrix_init(void) { + // TODO: initialize hardware and global matrix state here + + // Unless hardware debouncing - Init the configured debounce routine + debounce_init(MATRIX_ROWS); + + // This *must* be called for correct keyboard behavior + matrix_init_quantum(); +} + +uint8_t matrix_scan(void) { + bool matrix_has_changed = false; + + // TODO: add matrix scanning routine here + + // Unless hardware debouncing - use the configured debounce routine + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + + // This *must* be called for correct keyboard behavior + matrix_scan_quantum(); + + return matrix_has_changed; +} +``` + +And also provide defaults for the following callbacks: + +```c +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } + +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } + +__attribute__((weak)) void matrix_init_user(void) {} + +__attribute__((weak)) void matrix_scan_user(void) {} +``` diff --git a/custom_quantum_functions.md b/custom_quantum_functions.md new file mode 100644 index 00000000000..a459042b32e --- /dev/null +++ b/custom_quantum_functions.md @@ -0,0 +1,391 @@ +# How to Customize Your Keyboard's Behavior + +For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations. + +This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level. + +## A Word on Core vs Keyboards vs Keymap :id=a-word-on-core-vs-keyboards-vs-keymap + +We have structured QMK as a hierarchy: + +* Core (`_quantum`) + * Keyboard/Revision (`_kb`) + * Keymap (`_user`) + +Each of the functions described below can be defined with a `_kb()` suffix or a `_user()` suffix. We intend for you to use the `_kb()` suffix at the Keyboard/Revision level, while the `_user()` suffix should be used at the Keymap level. + +When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` before executing anything else- otherwise the keymap level function will never be called. + +# Custom Keycodes + +By far the most common task is to change the behavior of an existing keycode or to create a new keycode. From a code standpoint the mechanism for each is very similar. + +## Defining a New Keycode + +The first step to creating your own custom keycode(s) is to enumerate them. This means both naming them and assigning a unique number to that keycode. Rather than limit custom keycodes to a fixed range of numbers QMK provides the `SAFE_RANGE` macro. You can use `SAFE_RANGE` when enumerating your custom keycodes to guarantee that you get a unique number. + + +Here is an example of enumerating 2 keycodes. After adding this block to your `keymap.c` you will be able to use `FOO` and `BAR` inside your keymap. + +```c +enum my_keycodes { + FOO = SAFE_RANGE, + BAR +}; +``` + +## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode + +When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required. + +These function are called every time a key is pressed or released. + +### Example `process_record_user()` Implementation + +This example does two things. It defines the behavior for a custom keycode called `FOO`, and it supplements our Enter key by playing a tone whenever it is pressed. + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // Do something when pressed + } else { + // Do something else when release + } + return false; // Skip all further processing of this key + case KC_ENTER: + // Play a tone when enter is pressed + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // Let QMK send the enter press/release events + default: + return true; // Process all other keycodes normally + } +} +``` + +### `process_record_*` Function Documentation + +* Keyboard/Revision: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* Keymap: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` + +The `keycode` argument is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. You should use a `switch...case` block to handle these events. + +The `record` argument contains information about the actual press: + +```c +keyrecord_t record { + keyevent_t event { + keypos_t key { + uint8_t col + uint8_t row + } + bool pressed + uint16_t time + } +} +``` + +# Keyboard Initialization Code + +There are several steps in the keyboard initialization process. Depending on what you want to do, it will influence which function you should use. + +These are the three main initialization functions, listed in the order that they're called. + +* `keyboard_pre_init_*` - Happens before most anything is started. Good for hardware setup that you want running very early. +* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet. +* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part. + +!> For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow. + +## Keyboard Pre Initialization code + +This runs very early during startup, even before the USB has been started. + +Shortly after this, the matrix is initialized. + +For most users, this shouldn't be used, as it's primarily for hardware oriented initialization. + +However, if you have hardware stuff that you need initialized, this is the best place for it (such as initializing LED pins). + +### Example `keyboard_pre_init_user()` Implementation + +This example, at the keyboard level, sets up B0, B1, B2, B3, and B4 as LED pins. + +```c +void keyboard_pre_init_user(void) { + // Call the keyboard pre init code. + + // Set our LED pins as output + setPinOutput(B0); + setPinOutput(B1); + setPinOutput(B2); + setPinOutput(B3); + setPinOutput(B4); +} +``` + +### `keyboard_pre_init_*` Function Documentation + +* Keyboard/Revision: `void keyboard_pre_init_kb(void)` +* Keymap: `void keyboard_pre_init_user(void)` + +## Matrix Initialization Code + +This is called when the matrix is initialized, and after some of the hardware has been set up, but before many of the features have been initialized. + +This is useful for setting up stuff that you may need elsewhere, but isn't hardware related nor is dependant on where it's started. + + +### `matrix_init_*` Function Documentation + +* Keyboard/Revision: `void matrix_init_kb(void)` +* Keymap: `void matrix_init_user(void)` + + +## Keyboard Post Initialization code + +This is ran as the very last task in the keyboard initialization process. This is useful if you want to make changes to certain features, as they should be initialized by this point. + + +### Example `keyboard_post_init_user()` Implementation + +This example, running after everything else has initialized, sets up the rgb underglow configuration. + +```c +void keyboard_post_init_user(void) { + // Call the post init code. + rgblight_enable_noeeprom(); // enables Rgb, without saving settings + rgblight_sethsv_noeeprom(180, 255, 255); // sets the color to teal/cyan without saving + rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // sets mode to Fast breathing without saving +} +``` + +### `keyboard_post_init_*` Function Documentation + +* Keyboard/Revision: `void keyboard_post_init_kb(void)` +* Keymap: `void keyboard_post_init_user(void)` + +# Matrix Scanning Code + +Whenever possible you should customize your keyboard by using `process_record_*()` and hooking into events that way, to ensure that your code does not have a negative performance impact on your keyboard. However, in rare cases it is necessary to hook into the matrix scanning. Be extremely careful with the performance of code in these functions, as it will be called at least 10 times per second. + +### Example `matrix_scan_*` Implementation + +This example has been deliberately omitted. You should understand enough about QMK internals to write this without an example before hooking into such a performance sensitive area. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/Uq7gcHh). + +### `matrix_scan_*` Function Documentation + +* Keyboard/Revision: `void matrix_scan_kb(void)` +* Keymap: `void matrix_scan_user(void)` + +This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot. + +You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LEDs or a display) or other functionality that you want to trigger regularly even when the user isn't typing. + + +# Keyboard Idling/Wake Code + +If the board supports it, it can be "idled", by stopping a number of functions. A good example of this is RGB lights or backlights. This can save on power consumption, or may be better behavior for your keyboard. + +This is controlled by two functions: `suspend_power_down_*` and `suspend_wakeup_init_*`, which are called when the system board is idled and when it wakes up, respectively. + + +### Example suspend_power_down_user() and suspend_wakeup_init_user() Implementation + + +```c +void suspend_power_down_user(void) { + rgb_matrix_set_suspend_state(true); +} + +void suspend_wakeup_init_user(void) { + rgb_matrix_set_suspend_state(false); +} +``` + +### Keyboard suspend/wake Function Documentation + +* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` +* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` + +# Layer Change Code :id=layer-change-code + +This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling. + +### Example `layer_state_set_*` Implementation + +This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example. + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _RAISE: + rgblight_setrgb (0x00, 0x00, 0xFF); + break; + case _LOWER: + rgblight_setrgb (0xFF, 0x00, 0x00); + break; + case _PLOVER: + rgblight_setrgb (0x00, 0xFF, 0x00); + break; + case _ADJUST: + rgblight_setrgb (0x7A, 0x00, 0xFF); + break; + default: // for any other layers, or the default layer + rgblight_setrgb (0x00, 0xFF, 0xFF); + break; + } + return state; +} +``` + +Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer. + +Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state. + +### `layer_state_set_*` Function Documentation + +* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)` +* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)` + + +The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status) + + +# Persistent Configuration (EEPROM) + +This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM. + +The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function. + +Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU. + +* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated. + +### Example Implementation + +This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work! + + +In your keymap.c file, add this to the top: +```c +typedef union { + uint32_t raw; + struct { + bool rgb_layer_change :1; + }; +} user_config_t; + +user_config_t user_config; +``` + +This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written. + +We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything. + +Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like: +```c +void keyboard_post_init_user(void) { + // Call the keymap level matrix init. + + // Read the user config from EEPROM + user_config.raw = eeconfig_read_user(); + + // Set default layer, if enabled + if (user_config.rgb_layer_change) { + rgblight_enable_noeeprom(); + rgblight_sethsv_noeeprom_cyan(); + rgblight_mode_noeeprom(1); + } +} +``` +The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above. + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _RAISE: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } + break; + case _LOWER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } + break; + case _PLOVER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } + break; + case _ADJUST: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } + break; + default: // for any other layers, or the default layer + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } + break; + } + return state; +} +``` +This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this: +```c + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // Do something when pressed + } else { + // Do something else when release + } + return false; // Skip all further processing of this key + case KC_ENTER: + // Play a tone when enter is pressed + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // Let QMK send the enter press/release events + case RGB_LYR: // This allows me to use underglow as layer indication, or as normal + if (record->event.pressed) { + user_config.rgb_layer_change ^= 1; // Toggles the status + eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM + if (user_config.rgb_layer_change) { // if layer state indication is enabled, + layer_state_set(layer_state); // then immediately update the layer color + } + } + return false; + case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference) + if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled + if (user_config.rgb_layer_change) { // only if this is enabled + user_config.rgb_layer_change = false; // disable it, and + eeconfig_update_user(user_config.raw); // write the setings to EEPROM + } + } + return true; break; + default: + return true; // Process all other keycodes normally + } +} +``` +And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued. + +```c +void eeconfig_init_user(void) { // EEPROM is getting reset! + user_config.raw = 0; + user_config.rgb_layer_change = true; // We want this enabled by default + eeconfig_update_user(user_config.raw); // Write default value to EEPROM now + + // use the non noeeprom versions, to write these values to EEPROM too + rgblight_enable(); // Enable RGB by default + rgblight_sethsv_cyan(); // Set it to CYAN by default + rgblight_mode(1); // set to solid by default +} +``` + +And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to. + +### 'EECONFIG' Function Documentation + +* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)` +* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)` + +The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM. diff --git a/de/README.md b/de/README.md new file mode 100644 index 00000000000..bf8fbac57a9 --- /dev/null +++ b/de/README.md @@ -0,0 +1,33 @@ +# Quantum Mechanical Keyboard Firmware + +[![Aktuelle Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## Was ist QMK Firmware? + +QMK (*Quantum Mechanical Keyboard*) ist eine Open-Source-Community, welche die QMK-Firmware, die QMK-Toolbox, [qmk.fm](https://qmk.fm) und diese Dokumententation betreut. QMK-Firmware ist eine Weiterentwicklung der [tmk\_keyboard](http://github.com/tmk/tmk_keyboard)-Tastatur-Firmware mit vielen nützlichen Zusatzfunktionen für Atmel AVR-Prozessoren. Ursprünglich wurde sie für Produkte von [OLKB](http://olkb.com), das [ErgoDox EZ](http://www.ergodox-ez.com) und das [Clueboard](http://clueboard.co/) entwickelt. Im Laufe der Zeit wurde sie mit Hilfe von [ChibiOS](http://chibios.org) auch für die ARM-Architektur angepasst. Außerdem ist es inzwischen möglich, auch handverdrahtete Tastaturen und selbst geätzte PCBs mit QMK zu verwenden. + +## Bezugsquelle für QMK + +Wenn Du vorhast, deine Tastatur, Tastaturbelegung oder Features zu QMK beizusteuern, geht das am einfachsten, indem Du das [Repository auf GitHub](https://github.com/qmk/qmk_firmware#fork-destination-box) forkst, die Änderungen in deinem lokalen Repo vornimmst und anschließend einen [Pull Request](https://github.com/qmk/qmk_firmware/pulls) einreichst. + +Ansonsten kannst Du es als [zip](https://github.com/qmk/qmk_firmware/zipball/master) oder [tar](https://github.com/qmk/qmk_firmware/tarball/master) herunterladen, oder es direkt via git klonen (`git clone git@github.com:qmk/qmk_firmware.git` bzw. `git clone https://github.com/qmk/qmk_firmware.git`). + + +## Anleitung fürs Kompilieren + +Bevor Du in der Lage bist, die Firmware zu kompilieren, musst Du eine [Entwicklungsumgebung](de/getting_started_build_tools.md) für AVR und/oder ARM aufsetzen. Danach kannst Du mit dem `make` Befehl eine Keymap für deine Tastatur erzeugen. Die Notation dafür ist: + + make planck/rev4:default + +Dies generiert die Revision `rev4` für eine Tastatur vom Type `planck` mit der `default` Tastaturbelegung. Nicht alle Tastaturen haben Revisionen (auch bekannt als Subprojekt oder Unterordner) weswegen dies auch ausgelassen werden kann: + + make preonic:default + +## Möglichkeiten der Anpassung + +QMK hat viele [Features](de/features.md), die es zu entdecken gibt. In der [Dokumentation](https://docs.qmk.fmk) kannst Du Dir einen Überblick verschaffen. Die meisten Features basieren darauf, die [Tastaturbelegung](de/keymap.md) anzupassen und das Verhalten der [Keycodes](de/keycodes.md) zu verändern. diff --git a/de/_summary.md b/de/_summary.md new file mode 100644 index 00000000000..ffbd292bd45 --- /dev/null +++ b/de/_summary.md @@ -0,0 +1,122 @@ +* [Anleitung für Anfänger](de/newbs.md) + * [Erste Schritte](de/newbs_getting_started.md) + * [Die erste Firmware](de/newbs_building_firmware.md) + * [Firmware flashen](de/newbs_flashing.md) + * [Testen und Debuggen](de/newbs_testing_debugging.md) + * [Git Tips und Tricks](de/newbs_best_practices.md) + * [Hilfreiche Ressourcen](de/newbs_learn_more_resources.md) + +* [QMK Basics](de/README.md) + * [QMK Einführung](de/getting_started_introduction.md) + * [QMK CLI](de/cli.md) + * [QMK CLI Konfiguration](de/cli_configuration.md) + * [Zu QMK beitragen](de/contributing.md) + * [Anleitung für GitHub](de/getting_started_github.md) + * [Nach Hilfe fragen](de/getting_started_getting_help.md) + +* [Breaking Changes](de/breaking_changes.md) + * [2019 Aug 30](de/ChangeLog/20190830.md) + +* [FAQ](de/faq.md) + * [Häufige Fragen](de/faq_general.md) + * [Build/Kompilieren](de/faq_build.md) + * [Debugging/Troubleshooting](de/faq_debug.md) + * [Keymap](de/faq_keymap.md) + * [Treiber Installation mit Zadig](de/driver_installation_zadig.md) + +* Detailierte Guides + * [Build Tools installieren](de/getting_started_build_tools.md) + * [Vagrant Guide](de/getting_started_vagrant.md) + * [Build/Compile Anleitung](de/getting_started_make_guide.md) + * [Firmware flashen](de/flashing.md) + * [Funktionalität anpassen](de/custom_quantum_functions.md) + * [Keymap Überblick](de/keymap.md) + +* [Hardware](de/hardware.md) + * [AVR Prozessoren](de/hardware_avr.md) + * [Treiber](de/hardware_drivers.md) + +* Referenz + * [Tastatur Richtlinien](de/hardware_keyboard_guidelines.md) + * [Konfigurations Optionen](de/config_options.md) + * [Keycodes](de/keycodes.md) + * [Coding Konventionen - C](de/coding_conventions_c.md) + * [Coding Konventionen - Python](de/coding_conventions_python.md) + * [Dokumentations Best Practices](de/documentation_best_practices.md) + * [Dokumentations Templates](de/documentation_templates.md) + * [Glossar](de/reference_glossary.md) + * [Unit Testing](de/unit_testing.md) + * [Nützliche Funktionen](de/ref_functions.md) + * [Configurator Support](de/reference_configurator_support.md) + * [info.json Format](de/reference_info_json.md) + * [Python CLI Development](de/cli_development.md) + +* [Features](de/features.md) + * [Basic Keycodes](de/keycodes_basic.md) + * [US ANSI Shifted Keys](de/keycodes_us_ansi_shifted.md) + * [Quantum Keycodes](de/quantum_keycodes.md) + * [Advanced Keycodes](de/feature_advanced_keycodes.md) + * [Audio](de/feature_audio.md) + * [Auto Shift](de/feature_auto_shift.md) + * [Backlight](de/feature_backlight.md) + * [Bluetooth](de/feature_bluetooth.md) + * [Bootmagic](de/feature_bootmagic.md) + * [Combos](de/feature_combo.md) + * [Command](de/feature_command.md) + * [Debounce API](de/feature_debounce_type.md) + * [DIP Switch](de/feature_dip_switch.md) + * [Dynamic Macros](de/feature_dynamic_macros.md) + * [Encoders](de/feature_encoders.md) + * [Grave Escape](de/feature_grave_esc.md) + * [Haptic Feedback](de/feature_haptic_feedback.md) + * [HD44780 LCD Controller](de/feature_hd44780.md) + * [Key Lock](de/feature_key_lock.md) + * [Layouts](de/feature_layouts.md) + * [Leader Key](de/feature_leader_key.md) + * [LED Matrix](de/feature_led_matrix.md) + * [Macros](de/feature_macros.md) + * [Mouse Keys](de/feature_mouse_keys.md) + * [OLED Driver](de/feature_oled_driver.md) + * [One Shot Keys](de/one_shot_keys.md) + * [Pointing Device](de/feature_pointing_device.md) + * [PS/2 Mouse](de/feature_ps2_mouse.md) + * [RGB Lighting](de/feature_rgblight.md) + * [RGB Matrix](de/feature_rgb_matrix.md) + * [Space Cadet](de/feature_space_cadet.md) + * [Split Keyboard](de/feature_split_keyboard.md) + * [Stenography](de/feature_stenography.md) + * [Swap Hands](de/feature_swap_hands.md) + * [Tap Dance](de/feature_tap_dance.md) + * [Terminal](de/feature_terminal.md) + * [Thermal Printer](de/feature_thermal_printer.md) + * [Unicode](de/feature_unicode.md) + * [Userspace](de/feature_userspace.md) + * [Velocikey](de/feature_velocikey.md) + +* Für Maker und Modder + * [Hand Wiring Guide](de/hand_wire.md) + * [ISP Flashing Guide](de/isp_flashing_guide.md) + * [ARM Debugging Guide](de/arm_debugging.md) + * [I2C Driver](de/i2c_driver.md) + * [SPI Driver](de/spi_driver.md) + * [GPIO Controls](de/internals_gpio_control.md) + * [Proton C Conversion](de/proton_c_conversion.md) + +* Für ein tieferes Verständnis + * [Wie Tastaturen funktionieren](de/how_keyboards_work.md) + * [QMK verstehen](de/understanding_qmk.md) + +* Andere Themen + * [Eclipse mit QMK](de/other_eclipse.md) + * [VSCode mit QMK](de/other_vscode.md) + * [Support](de/getting_started_getting_help.md) + * [Übersetzungen](de/translating.md) + +* QMK Internals (In Progress) + * [Defines](de/internals_defines.md) + * [Input Callback Reg](de/internals_input_callback_reg.md) + * [Midi Device](de/internals_midi_device.md) + * [Midi Device Setup Process](de/internals_midi_device_setup_process.md) + * [Midi Util](de/internals_midi_util.md) + * [Send Functions](de/internals_send_functions.md) + * [Sysex Tools](de/internals_sysex_tools.md) diff --git a/de/cli.md b/de/cli.md new file mode 100644 index 00000000000..437062ad667 --- /dev/null +++ b/de/cli.md @@ -0,0 +1,169 @@ +# QMK CLI (Kommandozeile) + +Diese Seite beschreibt die Einrichtung und den Umgang mit dem QMK CLI (Kommandozeile). + +# Übersicht + +Die QMK CLI vereinfacht das Zusammenbauen und Arbeiten mit QMK Tastaturen. Hier findest Du wichtige Befehle, um beispielsweise das Herunterladen und Kompilieren der QMK Firmware oder das Erstellen von Tastaturbelegungen (und vieles mehr) zu erleichtern. + +* [Globale CLI](#globale-cli) +* [Lokale CLI](#lokale-cli) +* [CLI-Befehle](#cli-befehle) + +# System-Anforderungen + +Die CLI benötigt Python 3.5 oder höher. Außerdem ist es nötig, die Packages laut [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt) zu installieren. + +# Globale CLI + +QMK bietet ein installierbares CLI, das Du zum Einrichten Deiner QMK Build-Umgebung verwenden kannst. Dieses ermöglicht Dir das Arbeiten mit QMK, und erleichtert das Arbeiten mit mehreren Kopien der `qmk_firmware`. Wir empfehlen, dieses CLI zu installieren und regelmäßig upzudaten. + +## Installation mit Homebrew (macOS, manche Linux) + +Solltest Du [Homebrew](https://brew.sh) installiert haben, kannst Du QMK per tap installieren: + +``` +brew tap qmk/qmk +brew install qmk +export QMK_HOME='~/qmk_firmware' # Optional: setzt den Installationsort für `qmk_firmware` +qmk setup # Dies klont `qmk/qmk_firmware` und richtet optional auch Deine Build-Umgebung ein +``` + +## Installation mit easy_install oder pip + +Falls Du kein Homebrew hast, kannst Du QMK auch manuell installieren. Zuerst musst Du sicherstellen, dass Python 3.5 (oder höher) und pip installiert ist. Dann installiere QMK mit diesem Befehl: + +``` +pip3 install qmk +export QMK_HOME='~/qmk_firmware' # Optional: setzt den Installationsort für `qmk_firmware` +qmk setup # Dies klont `qmk/qmk_firmware` und richtet optional auch Deine Build-Umgebung ein +``` +## Installation mit git Repo + +`git clone https://github.com/qmk/qmk_cli.git && cd qmk_cli && python3 setup.py install` + +## Packaging für andere Betriebssysteme + +Wir suchen nach Freiwilligen, die ein `qmk`-Package für weitere Betriebssysteme erstellen und pflegen. Falls Du ein Package für Dein OS erstellen möchtest, bitte befolge diese Richtlinien: + +* Verwende "Best Practices" für Dein OS, sollten sie mit diesen Richtlinien in Konflikt stehen. + * Dokumentiere den Grund in einem Kommentar, wenn Du abweichen musstest. +* Installiere mit einem [virtualenv](https://virtualenv.pypa.io/en/latest/). +* Weise den User an, die Umgebungs-Variable `QMK_HOME` zu setzen, um die Firmware-Quelle anders einzustellen als `~/qmk_firmware`. + +# Lokale CLI + +Wenn Du die globale CLI nicht verwenden möchtest, beinhaltet `qmk_firmware` auch eine lokale CLI. Du kannst sie hier finden: `qmk_firmware/bin/qmk`. Du kannst den `qmk`-Befehl aus irgendeinem Datei-Verzeichnis ausführen und es wird immer auf dieser Kopie von `qmk_firmware` arbeiten. + +**Beispiel**: + +``` +$ ~/qmk_firmware/bin/qmk hello +Ψ Hello, World! +``` + +## Einschränkungen der lokalen CLI + +Hier ein Vergleich mit der globalen CLI: + +* Die lokale CLI unterstützt kein `qmk setup` oder `qmk clone`. +* Die lokale CLI arbeitet immer innerhalb der selben `qmk_firmware`-Verzeichnisstruktur, auch wenn Du mehrere Repositories geklont hast. +* Die lokale CLI läuft nicht in einer virtualenv. Daher ist es möglich, dass Abhängigkeiten (dependencies) miteinander in Konflikt kommen/stehen. + +# CLI-Befehle + +## `qmk compile` + +Dieser Befehl erlaubt es dir, die Firmware - aus egal welchem Datei-Verzeichnis - zu compilen. Du kannst JSON-Exporte von oder Keymaps in der Repo kompilen. + +**Anwendung für Konfigurations-Exports**: + +``` +qmk compile +``` + +**Anwendung für Keymaps**: + +``` +qmk compile -kb -km +``` + +## `qmk cformat` + +Dieser Befehl formatiert C-Code im clang-Format. Benutze ihn ohne Argumente, um den core-Code zu formatieren, oder benutze Namen von Dateien in der CLI, um den Befehl auf bestimmte Dateien anzuwenden. + +**Anwendung**: + +``` +qmk cformat [file1] [file2] [...] [fileN] +``` + +## `qmk config` + +Dieser Befehl konfiguriert das Verhalten von QMK. Für die volle `qmk config`-Dokumentation gehe zu [CLI-Konfiguration](cli_configuration.md). + +**Anwendung**: + +``` +qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] +``` + +## `qmk docs` + +Dieser Befehl startet einen lokalen HTTP-Server, den Du zum Browsen oder Verbessern der Dokumentation verwenden kannst. Der Default-Port ist 8936. + +**Anwendung**: + +``` +qmk docs [-p PORT] +``` + +## `qmk doctor` + +Dieser Befehl untersucht Deine Umgebung und warnt Dich vor potentiellen Build- oder Flash-Problemen. + +**Anwendung**: + +``` +qmk doctor +``` + +## `qmk list-keyboards` + +Dieser Befehl listet alle zurzeit in `qmk_firmware` definierten Tastaturen/Keyboards auf. + +**Anwendung**: + +``` +qmk list-keyboards +``` + +## `qmk new-keymap` + +Dieser Befehl erstellt eine neue Keymap basierend auf einer existierenden Standard-Keymap eines bestimmten Keyboards. + +**Anwendung**: + +``` +qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] +``` + +## `qmk pyformat` + +Dieser Befehl formatiert Python-Code in `qmk_firmware`. + +**Anwendung**: + +``` +qmk pyformat +``` + +## `qmk pytest` + +Dieser Befehl führt die Python Test Suite aus. Wenn Du Python-Code veränderst, solltest Du sicherstellen, dass der Test erfolgreich ausgeführt wurde. + +**Anwendung**: + +``` +qmk pytest +``` diff --git a/de/driver_installation_zadig.md b/de/driver_installation_zadig.md new file mode 100644 index 00000000000..bd04e05430b --- /dev/null +++ b/de/driver_installation_zadig.md @@ -0,0 +1,47 @@ +# Bootloader Treiber Installation mit Zadig + +QMK erscheint für den Host als normales HID Eingabegerät und benötigt deshalb keine zusätzlichen Treiber. Der Bootloader, den Du für das Flashen der Firmware benötigst, jedoch meistens schon. + +Hierzu gibt es zwei Ausnahmen: den Caterina Bootloader, meistens auf Pro Micros, sowie den HalfKay Bootloader auf PJRC Teensys. Diese erscheinen als serieller Port und als generisches HID Gerät und benötigen keine Treiber. + +Wir empfehlen deshalb [Zadig](https://zadig.akeo.ie/). Wenn Du die Entwicklungsumgebung mit MSYS2 oder WSL installiert hast, wird dich dass `qmk_install.sh` Skript gefragt haben, ob es die Treiber für dich installieren sollte. + +## Installation + +Versetze deine Tastatur in den Bootloader-Modus, entweder durch Betätigung des physischen `RESET` Schalters - meist auf der Unterseite der Platine - oder durch das Auslösen des Key-Codes `RESET` bzw. `KC_RESET` (sollte in der zur Tastatur gehörigen `keycode.c` zu entnehmen sein). Sollte deine Tastatur weder noch besitzen, versuche es damit die `Escape`-Taste oder `Leertaste + B` zu halten während Du die Tastatur mit dem PC verbindest (Siehe auch [Bootmagic](de/feature_bootmagic.md) für weitere Details). Ein paar Tastaturen benutzen das [Command](de/feature_command.md)-Feature an Stelle von Bootmagic; in diesem Fall kannst du mit den Tastenkombinationen `linkes Shift + rechtes Shift + B` oder `linkes Shift + rechtes Shift + Escape` zu jeder Zeit in den Bootloader wechseln solange die Tastatur verbunden ist. + +Eingie Tastaturen haben u.U. spezielle Anweisungen um in den Bootloader-Modus zu gelangen. Zum Beispiel kann die [Bootmagic-Lite](de/feature_bootmagic.md#bootmagic-lite)-Taste (default: Escape) auf eine andere Taste gemappt sein; oder die magische Kombination (default: linkes Shift+rechtes Shift) verwendet anstatt Shift die STRG-Tasten. Die zur Tastatur gehörige README sollte dir Aufschluss darüber geben wie der Bootloader-Modus ausgelöst werden kann wenn Du unsicher bist. + +Um ein Gerät mit USBaspLoader in den Bootloader-Modus zu versetzen, halte `BOOT` gedrückt während Du den `RESET`-Knopf drückst. +Alternativ, halte `BOOT` gedrückt während Du das USB-Kabel einsteckst. + +Zadig sollte das Bootloader-Gerät automatisch erkennen. Manchmal musst Du zusätzlich noch **Options → List All Devices** auswählen. + + - Tastaturen mit Atmel AVR MCUs sollten als `ATm32U4DFU` (oder ähnlich) angezeigt werden, mit der Vendor ID `03EB`. + - USBasp werden als `USBasp` angezeigt, mit VID/PID `16C0:05DC`. + - Tastaturen AVR controller und dem QMK-DFU Bootloader haben den namen ` Bootloader` und die VID `03EB`. + - Die meisten ARM Tastaturen werden als `STM32 BOOTLOADER` angezeigt, mit VID/PID `0483:DF11`. + +!> Sollte Zadig ein oder mehrere Geräte mit `HidUsb`-Treiber anzeigen, dann ist deine Tastatur wahrscheinlich nicht im Bootloader-Modus. Der Pfeil wird orange eingefärbt sein und Du wirst nach einer Bestätigung gefragt um Veränderungen am System vorzunehmen. In diesem Fall **fahre nicht fort**! + +Wenn der Pfeil grün angezeigt wird, wähle den Treiber aus und klicke auf **Treiber installieren**. Der `libusb-win32`-Treiber sollte gewöhnlich für AVR verwendet werden und `WinUSB` für ARM. Sollte es danach noch nicht möglich sein die Tastatur zu flashen, versuche es mit einem anderen Treiber. Für USBaspLoader Geräte, die über die Befehlszeile mit MSYS2 geflasht werden, wird der `libusbk`-Treiber empfohlen. Ansonsten sollte `libusb-win32` funktionieren wenn die QMK Toolbox verwendet wird. + +![Zadig mit Bootloader-Treiber korrekt installiert](https://i.imgur.com/b8VgXzx.png) + +Entferne nun deine Tastatur und verbinde sie erneut um sicherzugehen dass der neue Treiber erfolgreich installiert wurde. Wenn Du QMK Toolbox benutzt, starte die Anwendung zur Sicherheit einmal neu, da Veränderungen am Treiber manchmal nicht richtig erkannt werden. Wenn dies immer noch nicht erfolgreich war hilft es an dieser Stelle manchmal ein Neustart des Computers. + +## Wiederherstellung einer Installation für ein falsches Gerät + +Wenn Du feststellst dass Du anschließend auf deiner Tastatur nicht mehr tippen kannst, ist etwas bei der Installation schief gelaufen. Ein häufiger Fehler ist es dass die Tastatur nicht im Bootloader-Modus war und stattdessen der Treiber für das HID-Gerät ersetzt wurde. Dies kannst Du einfach mit Zadig überprüfen, eine funktionierende Tastatur verwendet als Treiber `HidUsb` auf allen Interfaces . + +![Eine funktionierende Tastatur aus Zadigs Sicht](https://i.imgur.com/Hx0E5kC.png) + +Öffne den Geräte-Manager und suche nach einem Gerät das wie deine Tastatur aussieht. + +![Die Tastatur mit dem falschen Treiber installiert, im Geräte-Manager](https://i.imgur.com/L3wvX8f.png) + +Rechtsklick und **Gerät deinstallieren** anklicken. Bitte gehe sicher dass in diesem Schritt auch **Treibersoftware für dieses Gerät löschen** markiert ist. + +![Der "Gerät deinstallieren"-Dialog, mit "Treibersoftware für dieses Gerät entfernen" markiert](https://i.imgur.com/aEs2RuA.png) + +Klick **Aktion → Suche nach veränderter Hardware**. Nun solltest Du wieder in der Lage sein normal zu tippen. Vergewissere dich mit Hilfe von Zadig dass die Tastatur nun `HidUsb` als Treiber verwendet. Wenn dies der Fall ist sollte wieder alles funktionieren. diff --git a/de/newbs.md b/de/newbs.md new file mode 100644 index 00000000000..61139a99e1b --- /dev/null +++ b/de/newbs.md @@ -0,0 +1,22 @@ +# Anleitung für absolute Beginner +QMK ist eine mächtige Open Source Firmware für mechanische Tastaturen. Mit QMK kannst Du deine Tastatur sowohl sehr einfach als auch sehr umfangreich anpassen. Menschen unterschiedlichen Wissensstandes - vom kompletten Anfänger bis zum erfahrenen Programmierer - haben ihre Tastaturen mit QMK erfolgreich auf ihre persönlichen Bedürfnisse angepasst. Diese Anleitung soll Dir unabhängig von deinen Vorkenntnissen dabei helfen dies ebenfalls zu bewältigen. + +Bist Du unsicher ob deine Tastatur QMK unterstützt? Wenn es eine mechanische Tastatur ist, die Du selbst gebaut hast, stehen deine Chancen gut. Wir unterstützen eine [Vielzahl](https://qmk.fm/keyboards/) selbst gebauter Tastaturen, sodass selbst wenn deine jetzige Tastatur nicht unterstützt wird Du keine Probleme haben solltest eine für deine Anforderungen zu finden. + +## Übersicht + +Diese Anleitung ist in 7 Abschnitte unterteilt: + +* [Die ersten Schritte](newbs_getting_started.md) +* [Die erste Firmware auf der Kommandozeile erzeugen](newbs_building_firmware.md) +* [Die erste Firmware mit der Online GUI erzeugen](newbs_building_firmware_configurator.md) +* [Firmware flashen](newbs_flashing.md) +* [Testen und Debuggen](newbs_testing_debugging.md) +* [Git Leitfaden](newbs_best_practices.md) +* [Weitere hilfreiche Ressourcen für Anfänger](newbs_learn_more_resources.md) + +Diese Anleitung richtet sich an Personen, die vorher noch nie Software kompiliert haben. Die Entscheidungen und Empfehlungen basieren auf dieser Grundannahme. Es gibt unterschiedliche Herangehensweisen für viele der Prozeduren und wir unterstützen die meisten Alternativen. Wenn Du mal nicht weiter weißt oder Dir nicht sicher bist, wie Du an ein Problem herangehen sollst, kannst Du uns gerne [um Hilfe bitten](getting_started_getting_help.md). + +## Weitere Ressourcen + +* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – Ein äußerst hilfreicher Blog eines Community-Mitglieds, der einige Grundlagen der QMK-Firmware aus der Sicht des Benutzers erklärt (auf Englisch). diff --git a/de/newbs_building_firmware.md b/de/newbs_building_firmware.md new file mode 100644 index 00000000000..b6d48402499 --- /dev/null +++ b/de/newbs_building_firmware.md @@ -0,0 +1,78 @@ +# Eine eigene Firmware erstellen + +Nachdem Du nun eine funktionierende Entwicklungsumgebung aufgesetzt hast, bist Du nun bereit, deine eigene Firmware zu erstellen. Dieses Sektion des Guides wird zwischen drei Programmen hin- und herwechseln: deinem Dateimanager, deinem Texteditor und der Befehlszeile. Lasse diese drei Fenster geöffnet, bis Du fertig und zufrieden mit deiner Tastatur-Firmware bist. + +Solltest Du die Befehlszeile zwischenzeitlich geschlossen haben, vergiss nicht wieder in das richtige Verzeichnis zu navigieren, benutze dazu den Befehl `cd qmk_firmware`. + +## Navigiere in deinen Keymap Ordner + +Beginne damit, in das `keymaps` Verzeichnis für deine Tastatur zu navigieren. + +Wenn Du macOS oder Windows benutzt, kannst Du einfach in das keymaps Verzeichnis wechseln. + +?> macOS:
+ open keyboards//keymaps + +?> Windows:
+ start .\\keyboards\\\\keymaps + +## Eine Kopie der `default` Tastaturbelegung erstellen + +Wenn Du den `keymaps` Ordner geöffnet hast, solltest Du zuerst eine Kopie des `default` Verzeichnisses erstellen. Wir empfehlen dafür deinen GitHub Benutzernamen zu verweden, aber Du kannst auch jeden anderen Namen verwenden solange er nur aus Kleinbuchstaben, Zahlen und Unterstrichen besteht. + +Um den Prozess zu automatisieren kannst Du dazu auch das Skript `new_keymap.sh` verwenden. + +Navigiere dazu in das `qmk_firmware/util` Verzeichnis und gib folgenden Befehl ein: + +``` +./new_keymap.sh +``` + +Um zum Beispiel den Benutzernamen John für die Tastaturbelegung eines 1up60hse zu verwenden, würdest Du Folgendes eingeben: + +``` +./new_keymap.sh 1upkeyboards/1up60hse john +``` + +## Öffne `keymap.c` in deinem bevorzugtem Text Editor + +Öffne deine `keymap.c`. In dieser Datei findest Du die Strukturen, die das Verhalten deiner Tastatur bestimmen. Oben in der `keymap.c` befinden sich Definitionen (defines) und Aufzählungen (enums), die die Tastaturbelegung leserlicher machen sollen. Weiter unten wirst Du eine Zeile finden, die wie folgt aussieht: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +Diese Zeile markiert den Anfang der Liste der Ebenen (Layers). Darunter befinden sich Zeilen die entweder `LAYOUT` oder `KEYMAP` enthalten, das deutet auf den Start einer Ebene hin. Danach folgt eine Liste von Tasten, die dieser Ebene zugewiesen sind. + +!> Beim Bearbeiten einer Tastaturbelegung solltest Du darauf achten, keine Kommata hinzuzufügen oder zu entfernen. Ansonsten kann dies dazu führen, dass deine Firmware nicht mehr kompiliert und es ist nicht immer einfach festzustellen, wo genau ein Komma zuviel oder zu wenig ist. Die letzte Zeile hat am Ende kein Komma, die Zeilen davor jedoch schon. + +## Personalisiere die Tastaturbelegung nach deinen Wünschen + +Wie Du diesen Schritt abschließt ist vollkommen Dir überlassen. Ändere die eine Sache die Dich stört oder verändere alles von Grund auf. Du kannst Ebenen entfernen die Du nicht brauchst oder Neue hinzufügen, bis zu 32 Stück. Die folgende Dokumentation verrät Dir was Du hier alles definieren kannst: + +* [Keycodes](de/keycodes.md) +* [Features](de/features.md) +* [FAQ](de/faq.md) + +?> Während Du langsam ein Gefühl dafür kriegst wie Keymaps funktionieren, solltest Du darauf achten nicht zuviel auf einmal zu verändern. Größere Änderungen machen es schwieriger, Probleme zu debuggen. + +## Deine Firmware erzeugen + +Wenn Du damit fertig bist, deine Tastaturbelegung anzupassen, musst Du noch die Firmware erzeugen. Öffne dazu wieder die Befehlszeile und führe folgenden Befehl aus: + + make : + +Wenn deine Tastaturbelegung z.B. "xyverz" heißt und Du die Belegung für ein rev5 planck erzeugen möchtest, lautet der Befehl: + + make planck/rev5:xyverz + +Während des Kompiliervorgangs wird viel Text auf dem Bildschirm ausgegeben. Es sollte am Ende mit etwas enden das ungefähr so aussieht: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex [OK] + * File size is fine - 18392/28672 +``` + +## Deine Firmware flashen +Bitte fahre mit [Firmware flashen](de/newbs_flashing.md) fort, um zu erfahren, wie Du deine neue Firmware auf deine Tastatur flashen kannst. diff --git a/de/newbs_flashing.md b/de/newbs_flashing.md new file mode 100644 index 00000000000..940438669e8 --- /dev/null +++ b/de/newbs_flashing.md @@ -0,0 +1,369 @@ +# Deine Tastatur flashen + +Nachdem deine Firmware nun fertig ist musst Du Sie noch auf deine Tastatur flashen. + +## Flash-Vorgang mit QMK Toolbox + +Der einfachste Weg deine Tastatur zu flashen ist mit Hilfe der [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) + +Leider ist die QMK Toolbox derzeit nur für Windows und macOS verfügbar. Wenn Du Linux benutzt (oder es vorziehst die Firmware mit der Kommandozeile zu flashen) solltest Du die Methode benutzen die [hier](de/newbs_flashing.md#tastatur-mit-der-befehlszeile-flashen) beschrieben wird. + +### Lade die Datei in QMK Toolbox + +Beginne damit die Datei in der QMK Toolbox Anwendung zu laden. Versichere dich dass Du die Firmware-Datei im Finder oder Explorer findest. Deine Tastatur-Firmware sollte entweder vom Typ `.hex` oder `.bin` sein sein. QMK sollte die für deine Tastatur entsprechende Datei automatisch in das Root-Verzeichnis (normalerweise `qmk_firmware`) kopieren. + +?> Wenn Du Windows oder macOS benutzt kannst Du mit folgenden Befehlen ganz einfach das aktuelle Firmware-Verzeichnis im Explorer oder Finder öffnen. + +#### Windows: + +``` start . ``` + +#### macOS: + +``` open . ``` + +Die Firmware-Dateien folgen dabei immer folgendem Schema: + + _.{bin,hex} + +Zum Beispiel würde ein `planck/rev5` mit der `default` Tastaturbelegung folgenden Dateinamen haben: + + planck_rev5_default.hex + +Wenn Du die Firmware-Datei gefunden hast kannst Du sie in das "Local file" ("Lokale Datei") Feld in der QMK Toolbox ziehen, alternativ kannst Du auf "Öffnen" klicken und in das Verzeichnis navigieren indem sich die Firmware-Datei befindet. + +### Die Tastatur in den DFU (Bootloader) Modus versetzen + +Um deine angepasste Firmware auf deine Tastatur zu flashen musst Du diese erst in einen speziellen "flashing"-Modus versetzen. Während die Tastatur in diesem Modus ist kannst Du nicht auf ihr tippen oder sie wie gewohnt als Tastatur benutzen. Es ist wichtig dass der flashing-Prozesses nicht unterbrochen oder die Tastatur ausstöpselst wird, da der Vorgang ansonst wiederholt werden muss. + +Verschiedene Tastaturen verwenden unterschiedliche Methoden um in den Bootloader-Modus zu gelangen. Wenn dein PCB im Moment QMK oder TMK verwendet und Du keine spezifischen Anweisungen erhalten hast probiere die folgenden Methoden in dieser Reihenfolge: + +* Halte beide Shift-Tasten und drücke `Pause` +* Halte beide Shift-Tasten und drücke `B` +* Entferne deine Tastatur vom Computer, drücke gleichzeitig `Leertaste` und `B`, verbinde die Tastatur wieder mit dem Computer und warte eine Sekunde bevor Du die Tasten wieder loslässt. +* Drücke den physischen `RESET`-Knopf auf der Unterseite des PCBs +* Suche auf dem PCB den Pin mit dem Label `RESET`, verbinde diesen mit deinem GND-Pin +* Suche auf dem PCB den Pin mit dem Label `BOOT0`, verbinde diesen mit GND und schließe die Tastatur wieder an den PC an TODO: DIS IS DANGEROUS!! + +Wenn Du damit erfolgreich warst solltest Du in der QMK Toolbox eine Nachricht sehen die ungefähr so aussieht: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +``` + +### Tastatur flashen + +Klicke auf den `Flash`-Knopf in der QMK Toolbox. Die Ausgabe wird ungefähr so aussehen: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash qmk_firmware/clueboard_66_hotswap_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset + +*** DFU device disconnected +*** Clueboard - Clueboard 66% HotSwap connected -- 0xC1ED:0x2390 +``` + +## Tastatur mit der Befehlszeile flashen + +Zunächst solltest Du versuchen herauszufinden welchen Bootlader deine Tastatur benutzt. Diese vier Bootloader sind am Weitesten verbreitet: + +| MCU | Bootloader | +| --- | --- | +| Pro-Micro und Klone | CATERINA | +| Teensy | Halfkay | +| OLKB Boards | QMK-DFU | +| sonstige atmega32u4 | DFU | + +Auf der Seite [Flash Anleitung und Bootloader Informationen](de/flashing.md) kannst Du mehr über das Thema erfahren. + +Wenn Du weißt welchen Bootloader deine Tastaur verwendet, kannst Du diese Information bei der Kompilation hinzufügen um den Flash-Vorgang mit dem `make`-Befehl zu automatisieren. +```rules.mk +... +BOOTLOADER = caterina +... +``` + +### DFU + +Wenn Du den DFU-Bootloader verwendest und Du bereit bist deine Firmware zu kompilieren und zu flashen, öffne ein Befehlszeile und führe folgenden Befehl aus: + + make ::dfu + +Wenn deine Tastaturbelegung z.B den Namen "xzverz" trägt und Du ein rev5 planck flashen möchtest sähe der Befehl wie folgt aus: + + make planck/rev5:xyverz:dfu + + +Nachdem der Vorgang abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex + * File size is fine - 18574/28672 + ``` + +Wenn dieser Punkt erreicht ist wird das Build-Skript alle 5 Sekunden nach einem DFU Bootloader suchen. Dieser Vorgang wird wiederholt bis er erfolgreich ist oder abgebrochen wird. + + dfu-programmer: no device present. + Error: Bootloader not found. Trying again in 5s. + +Wenn diese Nachricht erscheint konnte das Build-Skript den Controller nicht eigenständig in den DFU Modus versetzen (z.B. weil der Modus in rules.mk falsch gesetzt wurde oder ein Problem mit der Hardware besteht), wenn dies eintritt musst Du die oben beschrieben Schritte benutzen um den Controller in den DFU Modus zu versetzen. Danach sollte die Ausgabe ungefähr so aussehen: + +``` +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash qmk_firmware/clueboard_66_hotswap_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset +``` + +?> Wenn Du mit diesem Schritt Probleme hast (z.B. `dfu-programmer: no device present`) hilft dir hoffentlich der Abschnitt [Häufig gestellte Fragen (Build/Kompilieren)](de/faq_build.md). + +#### DFU Befehle + +Es gibt verschiedene DFU Befehle um die Firmware auf ein DFU Gerät zu flashen: + +* `:dfu` - Dies ist die default Option. Es wird gecheckt ob ein DFU Gerät verfügbar ist, ist dies der Fall wird die Firmware geflasht. Dieser Check wird alle 5 Sekunden ausgeführt bis ein DFU Gerät erkannt wird. +* `:dfu-ee` - Der Flash-Vorgang benutzt eine `.eep` Datei anstatt einer `.hex` Datei. Dies ist eher unüblich. +* `:dfu-split-left` - Dies flasht die Firmware wie gewohnt (`:dfu`). Allerdings nur die "linke Seite" der EEPROM für geteilte Tastaturen. _Dies ist ideal für auf Elite C basierenden geteilten Tastaturen._ +* `:dfu-split-right` - Dies flasht die Firmware wie gewohnt (`:dfu`). Allerdings nur die "rechte Seite" der EEPROM für geteilte Tastaturen. _Dies ist ideal für auf Elite C basierenden geteilten Tastaturen._ + + +### Caterina +Für Arduinos und andere ProMicro Klone (z.B. SparkFun ProMicro), wenn Du bereit bist zu kompilieren und die Tastatur zu flashen, öffne ein Befehlszeilen-Fenster und führe den Build-Befehl aus: + + make ::avrdude + +Wenn deine Tastaturbelegung zum Beispiel den Namen "xyverz" hat und Du eine Tastaturbelegung für ein "rev2 Lets Split" erzeugen möchtest, lautet der Befehl dafür: + + make lets_split/rev2:xyverz:avrdude + +Nachdem die Kompilation abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +``` +Linking: .build/lets_split_rev2_xyverz.elf [OK] +Creating load file for flashing: .build/lets_split_rev2_xyverz.hex [OK] +Checking file size of lets_split_rev2_xyverz.hex [OK] + * File size is fine - 27938/28672 +Detecting USB port, reset your controller now.............. +``` + +Nun wird die Tastatur automatisch zurückgesetzt und das Skript wird die Firmware flashen sobald es den Bootloader erkennt. Die Ausgabe sollte ungefähr so aussehen: + +``` +Detected controller on USB port at /dev/ttyS15 + +Connecting to programmer: . +Found programmer: Id = "CATERIN"; type = S + Software Version = 1.0; No Hardware Version given. +Programmer supports auto addr increment. +Programmer supports buffered memory access with buffersize=128 bytes. + +Programmer supports the following devices: + Device code: 0x44 + +avrdude.exe: AVR device initialized and ready to accept instructions + +Reading | ################################################## | 100% 0.00s + +avrdude.exe: Device signature = 0x1e9587 (probably m32u4) +avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed + To disable this feature, specify the -D option. +avrdude.exe: erasing chip +avrdude.exe: reading input file "./.build/lets_split_rev2_xyverz.hex" +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: writing flash (27938 bytes): + +Writing | ################################################## | 100% 2.40s + +avrdude.exe: 27938 bytes of flash written +avrdude.exe: verifying flash memory against ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: load data flash data from input file ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex contains 27938 bytes +avrdude.exe: reading on-chip flash data: + +Reading | ################################################## | 100% 0.43s + +avrdude.exe: verifying ... +avrdude.exe: 27938 bytes of flash verified + +avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:FF) + +avrdude.exe done. Thank you. +``` +Sollten dabei Probleme auftreten (z.B. "Zugriff verweigert" / "Permission denied") muss der Make-Befehl mit privilegierten Berechtigungen ausgeführt werden: + + sudo make ::avrdude + +Zusätzlich ist es möglich mehrere Tastaturen in einem Vorgang zu flashen: + + make ::avrdude-loop + +Du kannst den Loop mit STRG + C unterbrechen sobald der Vorgang abgeschlossen ist. Die korrekte Tastenkombination kann abweichen und hängt vom Betriebssystem ab. + + +### HalfKay + +Für Tastaturen mit PJRC Controllern (Teensy's), wenn Du bereit bist zu kompilieren und die Tastatur zu flashen, öffne ein Befehlszeilen-Fenster und führe den Build-Befehl aus: + + make ::teensy + +Wenn deine Tastaturbelegung zum Beispiel den Namen "xyverz" hat und Du eine Tastaturbelegung für ein Ergodox oder Ergodox EZ erzeugen möchtest, lautet der Befehl dafür: + + make ergodox_ez:xyverz:teensy + +Nachdem die Kompilation abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +``` +Linking: .build/ergodox_ez_xyverz.elf [OK] +Creating load file for flashing: .build/ergodox_ez_xyverz.hex [OK] +Checking file size of ergodox_ez_xyverz.hex [OK] + * File size is fine - 25584/32256 + Teensy Loader, Command Line, Version 2.1 +Read "./.build/ergodox_ez_xyverz.hex": 25584 bytes, 79.3% usage +Waiting for Teensy device... + (hint: press the reset button) + ``` + +An diesem Punkt solltest Du die Tastatur zurücksetzen um den Flash-Vorgang auszulösen. Wenn dies abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + + ``` +Found HalfKay Bootloader +Read "./.build/ergodox_ez_xyverz.hex": 28532 bytes, 88.5% usage +Programming............................................................. +................................................... +Booting +``` + +### BootloadHID + +Für auf Bootmapper Client(BMC)/bootloaderHID/ATmega32A basierende Tastaturen, wenn Du bereit bist zu kompilieren und die Tastatur zu flashen, öffne ein Befehlszeilen-Fenster und führe den Build-Befehl aus: + + make ::bootloaderHID + +Wenn deine Tastaturbelegung zum Beispiel den Namen "xyverz" hat und Du eine Tastaturbelegung für ein jj40 erzeugen möchtest, lautet der Befehl dafür: + + make jj40:xyverz:bootloaderHID + +Nachdem die Kompilation abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +``` +Linking: .build/jj40_default.elf [OK] +Creating load file for flashing: .build/jj40_default.hex [OK] +Copying jj40_default.hex to qmk_firmware folder [OK] +Checking file size of jj40_default.hex [OK] + * The firmware size is fine - 21920/28672 (6752 bytes free) +``` + +Wenn dieser Punkt erreicht ist wird das Build-Skript alle 5 Sekunden nach einem DFU Bootloader suchen. Dieser Vorgang wird wiederholt bis er erfolgreich ist oder abgebrochen wird. + +``` +Error opening HIDBoot device: The specified device was not found +Trying again in 5s. +``` + +An diesem Punkt solltest Du die Tastatur zurücksetzen um den Flash-Vorgang auszulösen. Wenn dies abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +``` +Page size = 128 (0x80) +Device size = 32768 (0x8000); 30720 bytes remaining +Uploading 22016 (0x5600) bytes starting at 0 (0x0) +0x05580 ... 0x05600 +``` + +### STM32 (ARM) + +Für die meisten ARM Tastaturen (inkl. Proton C, Planck Rev 6 und Preonic Rev 3), wenn Du bereit bist zu kompilieren und die Tastatur zu flashen, öffne ein Befehlszeilen-Fenster und führe den Build-Befehl aus: + + make ::dfu-util + +Wenn deine Tastaturbelegung zum Beispiel den Namen "xyverz" hat und Du eine Tastaturbelegung für ein Planck Revision 6 erzeugen möchtest, benutze dafür den folgenden Befehl und reboote die Tastatur in den Bootloader (kurz bevor der Kompiliervorgang abgeschlossen ist): + + make planck/rev6:xyverz:dfu-util + +Nachdem der Kompiliervorgang abgeschlossen ist sollte die Ausgabe ungefähr so aussehen: + +Für auf Bootmapper Client(BMC)/bootloaderHID/ATmega32A basierende Tastaturen, wenn Du bereit bist zu kompilieren und die Tastatur zu flashen, öffne ein Befehlszeilen-Fenster und führe den Build-Befehl aus: + + make ::bootloaderHID + +Wenn deine Tastaturbelegung zum Beispiel den Namen "xyverz" hat und Du eine Tastaturbelegung für ein jj40 erzeugen möchtest, lautet der Befehl dafür: +``` +Linking: .build/planck_rev6_xyverz.elf [OK] +Creating binary load file for flashing: .build/planck_rev6_xyverz.bin [OK] +Creating load file for flashing: .build/planck_rev6_xyverz.hex [OK] + +Size after: + text data bss dec hex filename + 0 41820 0 41820 a35c .build/planck_rev6_xyverz.hex + +Copying planck_rev6_xyverz.bin to qmk_firmware folder [OK] +dfu-util 0.9 + +Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. +Copyright 2010-2016 Tormod Volden and Stefan Schmidt +This program is Free Software and has ABSOLUTELY NO WARRANTY +Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ + +Invalid DFU suffix signature +A valid DFU suffix will be required in a future dfu-util release!!! +Opening DFU capable USB device... +ID 0483:df11 +Run-time device DFU version 011a +Claiming USB DFU Interface... +Setting Alternate Setting #0 ... +Determining device status: state = dfuERROR, status = 10 +dfuERROR, clearing status +Determining device status: state = dfuIDLE, status = 0 +dfuIDLE, continuing +DFU mode device DFU version 011a +Device returned transfer size 2048 +DfuSe interface name: "Internal Flash " +Downloading to address = 0x08000000, size = 41824 +Download [=========================] 100% 41824 bytes +Download done. +File downloaded successfully +Transitioning to dfuMANIFEST state +``` + +#### STM32 Befehle + +Für Tastaturen mit STM32 Controller sind die DFU Befehle wie folgt: + +* `:dfu-util` - The default command for flashing to STM32 devices. +* `:dfu-util` - Der Standard-Befehl für STM32 Geräte. +* `:dfu-util-wait` - Funktioniert wie der Standard-Befehl, aber mit einem 10 Sekunden Timeout bevor erneut versucht wird die Firmware zu flashen. Mit dem Parameter `TIME_DELAY=20` auf der Befehlszeile kann der Timeout beeinflusst werden. + * z.B.: `make ::dfu-util TIME_DELAY=5` +* `:dfu-util-split-left` - Gleiche Funktionsweise wie `dfu-util`, jedoch wird zusätzlich das EEPROM Setting "linke Seite" für geteilte Tastaturen gesetzt. +* `:dfu-util-split-right` - Gleiche Funktionsweise wie `dfu-util`, jedoch wird zusätzlich das EEPROM Setting "rechte Seite" für geteilte Tastaturen gesetzt. + +## Probier's aus! + +Herzlichen Glückwunsch! Deine individuell angepasst Firmware wurde auf deine Tastatur übertragen! + + Probiere deine neue Tastatur aus und gehe sicher dass alles wie gewünscht funktioniert. Wir haben einen weiteren Artikel zum Thema [Testen und Debuggen](de/newbs_testing_debugging.md) verfasst der sich mit Problembeseitigung beschäftigt um den Beginnger-Guide abzuschließen. diff --git a/de/newbs_getting_started.md b/de/newbs_getting_started.md new file mode 100644 index 00000000000..8240f2bafa0 --- /dev/null +++ b/de/newbs_getting_started.md @@ -0,0 +1,101 @@ +# Einleitung +Genau wie in einem Computer befindet sich auch in einer Tastatur ein Prozessor. + +Dieser Prozessor führt Software aus, die registriert wenn Tasten gedrückt bzw. wieder losgelassen werden und leitet die entsprechenden Signale an den Computer weiter. + +QMK übernimmt die Rolle dieser Software und teilt dem Host-Computer den aktuellen Zustand der Tastatur mit. Wenn Du eine Tastaturbelegung definierst, ist dies äquivalent zu einem ausführbarem Programm, das auf deiner Tastatur läuft. + +QMK möchte seine BenutzerInnen in die Lage versetzen, simple Aufgaben möglichst einfach zu gestalten und gleichzeitig komplexe Dinge zu ermöglichen, die mit normalen Tastaturen ohne zusätzliche Software undenkbar wären. Du musst nicht programmieren können, um abgefahrene Tastaturbelegungen zu gestalten - es reicht wenn Du eine Idee hast und ein paar einfache syntaktische Regeln verstehen kannst. + +# Los geht's! +Bevor Du damit loslegen kannst, deine Tastaturbelegung zu erstellen, musst Du ein wenig Software installieren und Dir eine Entwicklungsumgebung aufsetzen. Die gute Nachricht ist, dass das nur einmal erledigt werden muss, egal für wie viele verschiedene Tastaturen Du hinterher Firmware entwickeln willst. + +Wenn Du es vorziehst mit einer grafischen Oberfläche zu entwickeln kannst Du auch dazu gerne direkt mit dem online [QMK Konfigurator](https://config.qmk.fm) loslegen. Siehe auch: [Firmware mit der Online GUI erzeugen](de/newbs_building_firmware_configurator.md) + +## Software herunterladen + +### Text Editor + +Du wirst ein Programm benötigen, mit dem Du **plain text** (= reiner Text) Dateien bearbeiten und speichern kannst. Wenn Du Windows benutzt, reicht dafür schon das normale `Notepad` und für Linux z.B. `gedit` oder `leafpad`. Beide sind sehr rudimentäre Editoren deren Funktionsumfang aber vollkommen ausreicht. Für macOS' standard `TextEdit` muss man ein bisschen vorsichtig sein und darauf achten, beim Speichern explizit unter _Format_ die Option _Reiner Text_ auszuwählen. + +Ansonsten ist es empfehlenswert, einen Editor herunterzuladen der für die Programmierung und das Bearbeiten von Code ausgelegt ist wie z.b [Notepad++](http://notepad-plus-plus.org/), [Sublime Text](https://www.sublimetext.com/) oder [VS Code](https://code.visualstudio.com/). + +?> Immer noch unsicher, welcher Text Editor der Richtige für Dich ist? Laurence Bradford hat eine hervorragende [Einleitung](https://learntocodewith.me/programming/basics/text-editors/) zu dem Thema geschrieben (auf Englisch). + +### QMK Toolbox + +QMK Toolbox ist ein optionales grafisches Programm für Windows und macOS, das es erleichtern soll, deine Tastatur zu programmieren und zu debuggen. Du wirst es höchstwahrscheinlich früher oder später als unverzichtbar ansehen, wenn es darum geht eine Tastatur einfach zu flashen oder zu debuggen, da es ermöglicht, sich debug-Nachrichten direkt anzeigen zu lassen. + +[Hier kannst Du die aktuelle Version herunterladen.](https://github.com/qmk/qmk_toolbox/releases/latest) + +* Für Windows: `qmk_toolbox.exe` (portable) oder `qmk_toolbox_install.exe` (installer) +* Für macOS: `QMK.Toolbox.app.zip` (portable) oder `QMK.Toolbox.pkg` (installer) + +## Die Entwicklungsumgebung aufsetzen + + +Wir haben versucht, die Installation der Entwicklungsumgebung für QMK so einfach wie möglich zu gestalten. Alles, was Du tun musst, ist eine Linux oder Unix Umgebung aufzusetzen, danach macht QMK den Rest. + +?> Wenn Du das erste Mal mit der Linux/Unix Befehlszeile arbeitest, schadet es nicht, sich mit ein paar Grundlagen und Befehlen vertraut zu machen. Diese Ressourcen sollten ausreichen, um sich das Nötigste anzueignen um mit QMK arbeiten zu können:
+[Erforderliche Linux Grundlagen](https://www.guru99.com/must-know-linux-commands.html)
+[Noch ein paar Linux Befehle](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +Du wirst MSYS2 (o.Ä.) und Git benötigen. + +* Befolge die Installationsanleitung auf der [MSYS2 Homepage](http://www.msys2.org) +* Schließe alle offenen MSYS2 Fenster und öffne ein neues MSYS2 MinGW 64-bit Terminal +* Installiere Git mit dem Kommando: `pacman -S git` + +### macOS + +Du wirst Homebrew benötigen. Folge dafür den Anweisungen auf der [Homebrew homepage](https://brew.sh). + +Nachdem Homebrew erfolgreich installiert ist, kannst Du mit _QMK aufsetzen_ fortfahren. + +### Linux + +Du benötigst Git, aber es ist ziemlich wahrscheinlich, dass es bereits installiert ist. Sollte dies nicht der Fall sein, kannst Du es mit dem folgenden Aufruf installieren: + +* Debian / Ubuntu / Devuan: `apt-get install git` +* Fedora / Red Hat / CentOS: `yum install git` +* Arch Linux: `pacman -S git` + +?> Docker ist ebenfalls eine Option für alle Plattformen. [Hier](de/getting_started_build_tools.md#docker) kannst Du dazu weitere Informationen finden. + +## QMK aufsetzen +Wenn Du damit fertig bist, deine Linux/Unix Umgebung zu installieren, kannst Du damit fortfahren QMK herunterzuladen. Dafür werden wir mit Git das QMK Repository "klonen". Öffne ein Terminal oder ein MSYS2 MinGW Fenster, dies wirst Du für den Rest der Anleitung benötigen. In diesem Fenster rufst Du nun die beiden folgenden Kommandos auf: + +```shell +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` +?> Wenn Du bereits weißt, [wie man GitHub benutzt](de/getting_started_github.md), empfehlen wir, dass Du Dir ein eigenen Fork erstellst. Wenn Du nicht weißt, was das bedeuten soll, kannst Du diesen Ratschlag getrost ignorieren. + +QMK liefert ein Script mit, das helfen soll, Dir alles Weitere abzunehmen. Du kannst es mit dem folgenden Befehl aufrufen: + + util/qmk_install.sh + +## Die Build-Umgebung testen + +Nun sollte hoffentlich alles Nötige für eine funktionierende QMK Build-Umgebung installiert sein und Du solltest in der Lage sein, die QMK-Firmware zu kompilieren. Um dies mit einer `default` Tastaturbelegung zu testen, kannst Du den folgenden Befehl ausprobieren: + + make :default + +Der Befehl um z.B. die Firmware für ein _Clueboard 66%_ zu erzeugen lautet: + + make clueboard/66/rev3:default + +Wenn es fertig ist, sollte der Output ungefähr so ähnlich wie das Folgende aussehen: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +# Eine eigene Tastaturbelegung erstellen +Du bist nun fertig mit dem Setup der Entwicklungsumgebung und solltest somit in der Lage sein, deine eigenen Tastaturbelegungen zu erstellen. Um fortzufahren, folge bitte der nächsten Anleitung unter [Die erste Firmware](de/newbs_building_firmware.md). diff --git a/de/newbs_learn_more_resources.md b/de/newbs_learn_more_resources.md new file mode 100644 index 00000000000..ac5adb0c12f --- /dev/null +++ b/de/newbs_learn_more_resources.md @@ -0,0 +1,14 @@ +# Lernmaterial + +Diese weiterführenden Ressourcen sind darauf ausgerichtet, Neulingen der QMK Commmunity mehr Informationen und ein besseres Verständnis zu einzelnen Themen zu bieten. + +Git Ressourcen: + +* [Gutes allgemeines Tutorial](https://www.codecademy.com/learn/learn-git) (auf Englisch) +* [Git spielerisch anhand von Beispielen lernen](https://learngitbranching.js.org/) (auf Englisch) +* [Mehr über den allgemeinen Umgang mit GitHub](getting_started_github.md) +* [Mehr über Git im Bezug zu QMK](contributing.md) + +Mehr über die Arbeit mit der Befehlszeile: + +* [Gutes allgemeines Tutorial über die Arbeit mit der Befehlszeile](https://www.codecademy.com/learn/learn-the-command-line) (auf Englisch) diff --git a/de/newbs_testing_debugging.md b/de/newbs_testing_debugging.md new file mode 100644 index 00000000000..acc067e10f9 --- /dev/null +++ b/de/newbs_testing_debugging.md @@ -0,0 +1,100 @@ +# Testen und Debuggen + +Nachdem Du deine Tastatur mit deiner angepassten Firmware geflasht hast, ist es nun an der Zeit sie auszuprobieren. Mit ein bisschen Glück sollte alles ohne Probleme funktionieren, wenn dies nicht der Fall ist, soll dieses Dokument dir dabei helfen, herauszufinden wo das Problem liegt. + +## Testen + +Die Tastatur zu testen ist relativ selbsterklärend. Drücke jede der Tasten um dich zu versichern, dass der gesendete Keyode der ist, den du erwarten würdest. Dafür gibt es sogar ein paar Programme die helfen sollen, dass keine Taste ausgelassen wurde. + +Anmerkung: Diese Programme werden weder von QMK bereitgestellt oder gutgeheißen. + +* [Switch Hitter](https://elitekeyboards.com/switchhitter.php) (Nur für Windows) +* [Keyboard Viewer](https://www.imore.com/how-use-keyboard-viewer-your-mac) (Nur für Mac) +* [Keyboard Tester](http://www.keyboardtester.com) (Web basiert) +* [Keyboard Checker](http://keyboardchecker.com) (Web basiert) + +## Debuggen + +Deine Tastatur wird Debug Informationen liefern wenn Du `CONSOLE_ENABLE = yes` in deiner `rules.mk` gesetzt hast. Die default-Ausgabe ist sehr beschränkt und kann wenn nötig durch die Aktivierung des Debug-Modes erhöht werden. Benutze dafür entweder den `DEBUG` Keycode in deiner Tastaturbelegung, das [Command](de/feature_command.md)-Feature oder füge den folgenden Code zu deiner Tastaturbelegung hinzu. + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + +### Debuggen mit der QMK Toolbox + +Für kompatible Plattformen kann die [QMK Toolbox](https://github.com/qmk/qmk_toolbox) benutzt werden um Debug-Nachrichten deiner Tastatur anzuzeigen. + +### Debuggen mit hid_listen + +Bevorzugst Du es lieber auf der Befehlszeile zu debuggen? Dafür eignet sich das Programm [hid_listen](https://www.pjrc.com/teensy/hid_listen.html) von PJRC. Binaries sind für Windows, Linux und MacOS verfügbar. + + + +## Eigene Debug-Nachrichten senden + +Manchmal ist es hilfreich Debug-Nachrichten innerhalb deines eigenen [Custom Codes](de/custom_quantum_functions.md) zu drucken. Das ist ziemlich einfach. Beginne damit `print.h` am Anfang deiner Datei zu inkludieren: + + #include + +Danach stehen dir verschiedene Druck-Funktionen zur Verfügung: + +* `print("string")`: Druckt einen simplen String +* `uprintf("%s string", var)`: Druckt einen formatierten String +* `dprint("string")` Druckt einen simplen String, aber nur wenn der Debug-Mode aktiviert ist +* `dprintf("%s string", var)`: Druckt einen formatierten String, aber nur wenn der Debug-Mode aktiviert ist + +## Debug Beispiele + +Anbei findest Du eine Sammlung von hilfreichen Beispielen. Für weitere Informationen Informationen sei an dieser Stelle auf [Debugging/Troubleshooting QMK](de/faq_debug.md) verwiesen. + +### Which matrix position is this keypress? +### Welche Matrix Position hat dieser Tastenanschlag + +Beim Portieren, oder bei der Fehlerdiagnose von PCB Problemen, ist es nützlich sich anzeigen zu lassen ob ein Tastenanschlag richtig erkannt wurde. Um die Protokollierung für diesen Fall zu aktivieren, füge bitte folgenden Code zu deiner Tastaturbelegung `keymap.c` hinzu. + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // Wenn 'console' aktiviert ist wird die Matrix-Position und der Status jedes Tastenanschlags ausgegeben +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif + return true; +} +``` + +Beispiel Ausgabe: +```text +Waiting for device:....... +Listening: +KL: kc: 169, col: 0, row: 0, pressed: 1 +KL: kc: 169, col: 0, row: 0, pressed: 0 +KL: kc: 174, col: 1, row: 0, pressed: 1 +KL: kc: 174, col: 1, row: 0, pressed: 0 +KL: kc: 172, col: 2, row: 0, pressed: 1 +KL: kc: 172, col: 2, row: 0, pressed: 0 +``` + +### Wieviel Zeit wurde benötigt um einen Tastenanschlag zu detektieren? + +Wenn Performance-Probleme auftreten ist es hilfreich die Frequenz, mit der die Matrix gescannt wird, zu wissen. Um dies in diesem Fall zu aktiveren füge, den folgenden Code zu deiner Tastaturbelegung in `config.h` hinzu. + +```c +#define DEBUG_MATRIX_SCAN_RATE +``` + +Beispiel Ausgabe +```text + > matrix scan frequency: 315 + > matrix scan frequency: 313 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 +``` diff --git a/documentation_best_practices.md b/documentation_best_practices.md new file mode 100644 index 00000000000..c193fed6b86 --- /dev/null +++ b/documentation_best_practices.md @@ -0,0 +1,64 @@ +# Documentation Best Practices + +This page exists to document best practices when writing documentation for QMK. Following these guidelines will help to keep a consistent tone and style, which will in turn help other people more easily understand QMK. + +# Page Opening + +Your documentation page should generally start with an H1 heading, followed by a 1 paragraph description of what the user will find on this page. Keep in mind that this heading and paragraph will sit next to the Table of Contents, so keep the heading short and avoid long strings with no whitespace. + +Example: + +``` +# My Page Title + +This page covers my super cool feature. You can use this feature to make coffee, squeeze fresh oj, and have an egg mcmuffin and hashbrowns delivered from your local macca's by drone. +``` + +# Headings + +Your page should generally have multiple "H1" headings. Only H1 and H2 headings will included in the Table of Contents, so plan them out appropriately. Excess width should be avoided in H1 and H2 headings to prevent the Table of Contents from getting too wide. + +# Styled Hint Blocks + +You can have styled hint blocks drawn around text to draw attention to it. + +### Important + +``` +!> This is important +``` + +Renders as: + +!> This is important + +### General Tips + +``` +?> This is a helpful tip. +``` + +Renders as: + +?> This is a helpful tip. + + +# Documenting Features + +If you create a new feature for QMK, create a documentation page for it. It doesn't have to be very long, a few sentences describing your feature and a table listing any relevant keycodes is enough. Here is a basic template: + +```markdown +# My Cool Feature + +This page describes my cool feature. You can use my cool feature to make coffee and order cream and sugar to be delivered via drone. + +## My Cool Feature Keycodes + +|Long Name|Short Name|Description| +|---------|----------|-----------| +|KC_COFFEE||Make Coffee| +|KC_CREAM||Order Cream| +|KC_SUGAR||Order Sugar| +``` + +Place your documentation into `docs/feature_.md`, and add that file to the appropriate place in `docs/_summary.md`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page. diff --git a/documentation_templates.md b/documentation_templates.md new file mode 100644 index 00000000000..8df25590c4f --- /dev/null +++ b/documentation_templates.md @@ -0,0 +1,40 @@ +# Documentation Templates + +This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK. + +## Keymap `readme.md` Template :id=keyboard-readmemd-template + +Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](http://imgur.com) or another hosting service, please do not include images in your Pull Request. + +Below the image you should write a short description to help people understand your keymap. + +``` +![Clueboard Layout Image](http://i.imgur.com/7Capi8W.png) + +# Default Clueboard Layout + +This is the default layout that comes flashed on every Clueboard. For the most +part it's a straightforward and easy to follow layout. The only unusual key is +the key in the upper left, which sends Escape normally, but Grave when any of +the Ctrl, Alt, or GUI modifiers are held down. +``` + +## Keyboard `readme.md` Template + +``` +# Planck + +![Planck](http://i.imgur.com/q2M3uEU.jpg) + +A compact 40% (12x4) ortholinear keyboard kit made and sold by OLKB and Massdrop. [More info on qmk.fm](http://qmk.fm/planck/) + +* Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert) +* Hardware Supported: Planck PCB rev1, rev2, rev3, rev4, Teensy 2.0 +* Hardware Availability: [OLKB.com](https://olkb.com), [Massdrop](https://www.massdrop.com/buy/planck-mechanical-keyboard?mode=guest_open) + +Make example for this keyboard (after setting up your build environment): + + make planck/rev4:default + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). +``` diff --git a/driver_installation_zadig.md b/driver_installation_zadig.md new file mode 100644 index 00000000000..4519a21e6b5 --- /dev/null +++ b/driver_installation_zadig.md @@ -0,0 +1,48 @@ +# Bootloader Driver Installation with Zadig + +QMK presents itself to the host as a regular HID keyboard device, and as such requires no special drivers. However, in order to flash your keyboard on Windows, the bootloader device that appears when you reset the board often *does*. + +There are two notable exceptions: the Caterina bootloader, usually seen on Pro Micros, and the HalfKay bootloader shipped with PJRC Teensys, appear as a serial port and a generic HID device respectively, and so do not require a driver. + +We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have set up the development environment with MSYS2, the `qmk_install.sh` script will have already installed the drivers for you. + +## Installation + +Put your keyboard into bootloader mode, either by hitting the `RESET` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in. +Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md#bootmagic-lite) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure. + +To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button. +Alternatively, hold `BOOT` while inserting the USB cable. + +Zadig will automatically detect the bootloader device. You may sometimes need to check **Options → List All Devices**. + + - For keyboards with Atmel AVR MCUs, the bootloader will be named something similar to `ATm32U4DFU`, and have a Vendor ID of `03EB`. + - USBasp bootloaders will appear as `USBasp`, with a VID/PID of `16C0:05DC`. + - AVR keyboards flashed with the QMK-DFU bootloader will be named ` Bootloader` and will also have the VID `03EB`. + - For most ARM keyboards, it will be called `STM32 BOOTLOADER`, and have a VID/PID of `0483:DF11`. + +!> If Zadig lists one or more devices with the `HidUsb` driver, your keyboard is probably not in bootloader mode. The arrow will be colored orange and you will be asked to confirm modifying a system driver. **Do not** proceed if this is the case! + +If the arrow appears green, select the driver, and click **Install Driver**. The `libusb-win32` driver will usually work for AVR, and `WinUSB` for ARM, but if you still cannot flash the board, try installing a different driver from the list. USBAspLoader devices must use the `libusbK` driver. + +![Zadig with a bootloader driver correctly installed](https://i.imgur.com/b8VgXzx.png) + +Finally, unplug and replug the keyboard to make sure the new driver has been loaded. If you are using the QMK Toolbox to flash, exit and restart it too, as it can sometimes fail to recognize the driver change. + +## Recovering from Installation to Wrong Device + +If you find that you can no longer type with the keyboard, you may have accidentally replaced the driver for the keyboard itself instead of for the bootloader. This can happen when the keyboard is not in the bootloader mode. You can easily confirm this in Zadig - a healthy keyboard has the `HidUsb` driver installed on all of its interfaces: + +![A healthy keyboard as seen by Zadig](https://i.imgur.com/Hx0E5kC.png) + +Open the Device Manager and look for a device that looks like your keyboard. + +![The board with the wrong driver installed, in Device Manager](https://i.imgur.com/L3wvX8f.png) + +Right-click it and hit **Uninstall device**. Make sure to tick **Delete the driver software for this device** first. + +![The Device Uninstall dialog, with the "delete driver" checkbox ticked](https://i.imgur.com/aEs2RuA.png) + +Click **Action → Scan for hardware changes**. At this point, you should be able to type again. Double check in Zadig that the keyboard device(s) are using the `HidUsb` driver. If so, you're all done, and your board should be functional again! + +?> A full reboot of your computer may sometimes be necessary at this point, to get Windows to pick up the new driver. diff --git a/eeprom_driver.md b/eeprom_driver.md new file mode 100644 index 00000000000..188b95caa76 --- /dev/null +++ b/eeprom_driver.md @@ -0,0 +1,71 @@ +# EEPROM Driver Configuration :id=eeprom-driver-configuration + +The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present. + +Driver | Description +-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below. +`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below. +`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below. +`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost. + +## Vendor Driver Configuration :id=vendor-eeprom-driver-configuration + +#### STM32 L0/L1 Configuration :id=stm32l0l1-eeprom-driver-configuration + +!> Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used. + +`config.h` override | Description | Default Value +------------------------------------|--------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------- +`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled. + +## I2C Driver Configuration :id=i2c-eeprom-driver-configuration + +Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h: + +`config.h` override | Description | Default Value +------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------ +`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000 +`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)` +`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192 +`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32 +`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2 +`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5 + +Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`. + +Alternatively, there are pre-defined hardware configurations for available chips/modules: + +Module | Equivalent `#define` | Source +-----------------|---------------------------------|------------------------------------------ +CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | +RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | +24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | +24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | +MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | + +?> If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`. + +## SPI Driver Configuration :id=spi-eeprom-driver-configuration + +Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h: + +`config.h` override | Description | Default Value +-----------------------------------------------|--------------------------------------------------------------------------------------|-------------- +`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | SPI Slave select pin in order to inform that the EEPROM is currently being addressed | _none_ +`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | Clock divisor used to divide the peripheral clock to derive the SPI frequency | `64` +`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192 +`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32 +`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2 + +!> There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero. + +## Transient Driver configuration :id=transient-eeprom-driver-configuration + +The only configurable item for the transient EEPROM driver is its size: + +`config.h` override | Description | Default Value +------------------------------- | ----------------------------------------- | ------------- +`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64 + +Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`. diff --git a/es/README.md b/es/README.md new file mode 100644 index 00000000000..75fd3cb64e0 --- /dev/null +++ b/es/README.md @@ -0,0 +1,32 @@ +# Firmware Quantum Mechanical Keyboard + +[![Versión actual](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Estado de Build](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Estado de la documentación](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![Contribuyentes en GitHub](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![Forks en GitHub](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## ¿Qué es el firmware QMK? + +QMK (*Quantum Mechanical Keyboard*) es una comunidad open source que mantiene el firmware QMK, QMK Toolbox, qmk.fm, y estos documentos. El firmware QMK es un firmware para teclados basado en [tmk\_keyboard](http://github.com/tmk/tmk_keyboard) con algunas características útiles para controladores Atmel AVR, y más específicamente, la [línea de productos OLKB](http://olkb.com), el teclado [ErgoDox EZ](http://www.ergodox-ez.com), y la [línea de productos Clueboard](http://clueboard.co/). También ha sido portado a chips ARM chips usando ChibiOS. Lo puedes utilizar para manejar tu propio teclado ya sea cableado a mano o basado en una PCB personalizada. + +## Cómo conseguirlo + +Si estás pensando en contribuir con un keymap, teclado, or característica a QMK, la manera más sencilla es hacer un [fork del repositorio en GitHub](https://github.com/qmk/qmk_firmware#fork-destination-box), y clonar tu repositorio localmente para hacer los cambios, subirlos, y abir un [Pull Request](https://github.com/qmk/qmk_firmware/pulls) desde tu fork. + +De cualquier manera, también puedes descargarlo directamente en formatos ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), o clonarlo via git (`git@github.com:qmk/qmk_firmware.git`), o https (`https://github.com/qmk/qmk_firmware.git`). + +## Cómo compilar + +Antes de poder compilar, necesitarás [instalar un entorno](es/getting_started_build_tools.md) para el desarrollo de AVR y/o ARM. Una vez hayas completado este paso, usarás el comando `make` para compilar un teclado y keymap con la siguiente notación: + + make planck/rev4:default + +Este ejemplo compilaría la revisión `rev4` del teclado `planck` con el keymap `default`. No todos los teclados tienen revisiones (también llamados subproyectos o carpetas), en ese caso, se puede omitir: + + make preonic:default + +## Cómo personalizar + +QMK tiene montones de [características](es/features.md) para explorar, y una buena cantidad de [documentación de referencia](http://docs.qmk.fm) en la que sumergirse. Se pueden sacar provecho de la mayoría de las características modificando tu [keymap](es/keymap.md), y cambiando los [keycodes](es/keycodes.md). diff --git a/es/_summary.md b/es/_summary.md new file mode 100644 index 00000000000..aa2a0ca5d97 --- /dev/null +++ b/es/_summary.md @@ -0,0 +1,122 @@ +* [Guía completa para novatos](es/newbs.md) + * [Empezando](es/newbs_getting_started.md) + * [Construyendo tu primer firmare](es/newbs_building_firmware.md) + * [Flasheando el firmware](es/newbs_flashing.md) + * [Testeando y depurando ](es/newbs_testing_debugging.md) + * [Mejores práticas](es/newbs_best_practices.md) + * [Recursos de aprendizaje](es/newbs_learn_more_resources.md) + +* [QMK Basics](es/README.md) + * [Introducción a QMK](es/getting_started_introduction.md) + * [QMK CLI](es/cli.md) + * [Configuración de QMK CLI](es/cli_configuration.md) + * [Contribuyendo a QMK](es/contributing.md) + * [Cómo usar GitHub](es/getting_started_github.md) + * [Obtener ayuda](es/getting_started_getting_help.md) + +* [Cambios incompatibles](es/breaking_changes.md) + * [30 Ago 2019](es/ChangeLog/20190830.md) + +* [Preguntas frecuentes](es/faq.md) + * [General](es/faq_general.md) + * [Construir/Compilar QMK](es/faq_build.md) + * [Depurando/Encontrando problemas en QMK](es/faq_debug.md) + * [Keymap](es/faq_keymap.md) + * [Instalación de drivers con Zadig](es/driver_installation_zadig.md) + +* Guías detalladas + * [Instalar herramientas construcción](es/getting_started_build_tools.md) + * [Guía Vagrant](es/getting_started_vagrant.md) + * [Instrucciones de Construcción/Compilado](es/getting_started_make_guide.md) + * [Flasheando Firmware](es/flashing.md) + * [Personalizando funcionalidad](es/custom_quantum_functions.md) + * [Visión general del Keymap](es/keymap.md) + +* [Hardware](es/hardware.md) + * [Procesadores AVR](es/hardware_avr.md) + * [Drivers](es/hardware_drivers.md) + +* Referencia + * [Pautas de teclados](es/hardware_keyboard_guidelines.md) + * [Opciones de configuración](es/config_options.md) + * [Keycodes](es/keycodes.md) + * [Convenciones de código - C](es/coding_conventions_c.md) + * [Convenciones de código - Python](es/coding_conventions_python.md) + * [Mejores prácticas de documentación](es/documentation_best_practices.md) + * [Plantillas de documentación](es/documentation_templates.md) + * [Glosario](es/reference_glossary.md) + * [Tests unitarios](es/unit_testing.md) + * [Funciones útiles](es/ref_functions.md) + * [Sporte configurador](es/reference_configurator_support.md) + * [Formato info.json](es/reference_info_json.md) + * [Desarrollo Python CLI](es/cli_development.md) + +* [Características](es/features.md) + * [Keycodes Básicos](es/keycodes_basic.md) + * [Teclas US ANSI Shifted](es/keycodes_us_ansi_shifted.md) + * [Keycodes Quantum](es/quantum_keycodes.md) + * [Keycodes Avanzados](es/feature_advanced_keycodes.md) + * [Audio](es/feature_audio.md) + * [Auto Shift](es/feature_auto_shift.md) + * [Retroiluminación](es/feature_backlight.md) + * [Bluetooth](es/feature_bluetooth.md) + * [Bootmagic](es/feature_bootmagic.md) + * [Combos](es/feature_combo.md) + * [Comando](es/feature_command.md) + * [API Debounce](es/feature_debounce_type.md) + * [Switch DIP](es/feature_dip_switch.md) + * [Macros Dinámicas](es/feature_dynamic_macros.md) + * [Encoders](es/feature_encoders.md) + * [Grave Escape](es/feature_grave_esc.md) + * [Feedback Háptico](es/feature_haptic_feedback.md) + * [Controlador LCD HD44780](es/feature_hd44780.md) + * [Key Lock](es/feature_key_lock.md) + * [Layouts](es/feature_layouts.md) + * [Tecla Leader](es/feature_leader_key.md) + * [Matriz LED](es/feature_led_matrix.md) + * [Macros](es/feature_macros.md) + * [Teclas del ratón](es/feature_mouse_keys.md) + * [Driver OLED](es/feature_oled_driver.md) + * [Teclas One Shot](es/one_shot_keys.md) + * [Dispositivo de apuntado](es/feature_pointing_device.md) + * [Ratón PS/2](es/feature_ps2_mouse.md) + * [Iluminación RGB](es/feature_rgblight.md) + * [Matriz RGB](es/feature_rgb_matrix.md) + * [Cadete espacial](es/feature_space_cadet.md) + * [Teclado dividido](es/feature_split_keyboard.md) + * [Stenografía](es/feature_stenography.md) + * [Swap Hands](es/feature_swap_hands.md) + * [Tap Dance](es/feature_tap_dance.md) + * [Terminal](es/feature_terminal.md) + * [Impresora Térmica](es/feature_thermal_printer.md) + * [Unicode](es/feature_unicode.md) + * [Userspace](es/feature_userspace.md) + * [Velocikey](es/feature_velocikey.md) + +* Para Makers y Modders + * [Guía de cableado a mano](es/hand_wire.md) + * [Guía de flasheado de ISP](es/isp_flashing_guide.md) + * [Guía de depuración de ARM](es/arm_debugging.md) + * [Driver I2C](es/i2c_driver.md) + * [Driver SPI](es/spi_driver.md) + * [Controles GPIO](es/internals_gpio_control.md) + * [Conversión Proton C](es/proton_c_conversion.md) + +* Para entender en profundidad + * [Cómo funcionan los teclados](es/how_keyboards_work.md) + * [Entendiendo QMK](es/understanding_qmk.md) + +* Otros temas + * [Usando Eclipse con QMK](es/other_eclipse.md) + * [Usando VSCode con QMK](es/other_vscode.md) + * [Soporte](es/getting_started_getting_help.md) + * [Cómo añadir traducciones](es/translating.md) + +* QMK Internals (En progreso) + * [Defines](es/internals_defines.md) + * [Input Callback Reg](es/internals_input_callback_reg.md) + * [Dispositivo Midi](es/internals_midi_device.md) + * [Proceso de configuración de un dispositivo Midi](es/internals_midi_device_setup_process.md) + * [Utilidad Midi](es/internals_midi_util.md) + * [Funciones Send](es/internals_send_functions.md) + * [Herramientas Sysex](es/internals_sysex_tools.md) diff --git a/es/hardware.md b/es/hardware.md new file mode 100644 index 00000000000..8d7579c9efe --- /dev/null +++ b/es/hardware.md @@ -0,0 +1,8 @@ +# Hardware + +QMK es compatible con una variedad de hardware. Si tu procesador puede ser dirigido por [LUFA](http://www.fourwalledcubicle.com/LUFA.php) o [ChibiOS](http://www.chibios.com), probablemente puedes hacer que QMK se ejecute en él. Esta sección explora cómo hacer que QMK se ejecute y se comunique con hardware de todo tipo. + +* [Pautas de teclados](hardware_keyboard_guidelines.md) +* [Procesadores AVR](hardware_avr.md) +* Procesadores ARM (TBD) +* [Drivers](hardware_drivers.md) diff --git a/es/hardware_avr.md b/es/hardware_avr.md new file mode 100644 index 00000000000..2ecf78d662f --- /dev/null +++ b/es/hardware_avr.md @@ -0,0 +1,180 @@ +# Teclados con Procesadores AVR + +Esta página describe el soporte para procesadores AVR en QMK. Los procesadores AVR incluyen el atmega32u4, atmega32u2, at90usb1286, y otros procesadores de la Corporación Atmel. Los procesadores AVR son MCUs de 8-bit que son diseñados para ser fáciles de trabajar. Los procesadores AVR más comunes en los teclados tienen USB y un montón de GPIO para permitir grandes matrices de teclado. Son los MCUs más populares para el uso en los teclados hoy en día. + +Si aún no lo has hecho, debes leer las [Pautas de teclados](hardware_keyboard_guidelines.md) para tener una idea de cómo los teclados encajan en QMK. + +## Añadir tu Teclado AVR a QMK + +QMK tiene varias características para simplificar el trabajo con teclados AVR. Para la mayoría de los teclados no tienes que escribir ni una sola línea de código. Para empezar, ejecuta el archivo `util/new_keyboard.sh`: + +``` +$ ./util/new_keyboard.sh +Generating a new QMK keyboard directory + +Keyboard Name: mycoolkb +Keyboard Type [avr]: +Your Name [John Smith]: + +Copying base template files... done +Copying avr template files... done +Renaming keyboard files... done +Replacing %KEYBOARD% with mycoolkb... done +Replacing %YOUR_NAME% with John Smith... done + +Created a new keyboard called mycoolkb. + +To start working on things, cd into keyboards/mycoolkb, +or open the directory in your favourite text editor. +``` + +Esto creará todos los archivos necesarios para tu nuevo teclado, y rellenará la configuración con valores predeterminados. Ahora sólo tienes que personalizarlo para tu teclado. + +## `readme.md` + +Aquí es donde describirás tu teclado. Por favor sigue la [Plantilla del readme de teclados](documentation_templates.md#keyboard-readmemd-template) al escribir tu `readme.md`. Te animamos a colocar una imagen en la parte superior de tu `readme.md`. Por favor, utiliza un servicio externo como [Imgur](http://imgur.com) para alojar las imágenes. + +## `.c` + +Aquí es donde pondrás toda la lógica personalizada para tu teclado. Muchos teclados no necesitan nada aquí. Puedes aprender más sobre cómo escribir lógica personalizada en [Funciones Quantum Personalizadas](custom_quantum_functions.md). + +## `.h` + +Este es el archivo en el que defines tu(s) [Macro(s) de Layout](feature_layouts.md). Por lo menos deberías tener un `#define LAYOUT` para tu teclado que se ve algo así: + +```c +#define LAYOUT( \ + k00, k01, k02, \ + k10, k11 \ +) { \ + { k00, k01, k02 }, \ + { k10, KC_NO, k11 }, \ +} +``` + +La primera mitad de la macro pre-procesador `LAYOUT` define la disposición física de las llaves. La segunda mitad de la macro define la matriz a la que están conectados los interruptores. Esto te permite tener una disposición física de las llaves que difiere de la matriz de cableado. + +Cada una de las variables `k__` tiene que ser única, y normalmente sigue el formato `k`. + +La matriz física (la segunda mitad) debe tener un número de filas igualando `MATRIX_ROWS`, y cada fila debe tener exactamente `MATRIX_COLS` elementos. Si no tienes tantas teclas físicas puedes usar `KC_NO` para rellenar los espacios en blanco. + +## `config.h` + +El archivo `config.h` es donde configuras el hardware y el conjunto de características para tu teclado. Hay un montón de opciones que se pueden colocar en ese archivo, demasiadas para listar allí. Para obtener una visión de conjunto completa de las opciones disponibles consulta la página de [Opciones de Configuración](config_options.md). + +### Configuración de hardware + + +En la parte superior de `config.h` encontrarás ajustes relacionados con USB. Estos controlan la apariencia de tu teclado en el Sistema Operativo. Si no tienes una buena razón para cambiar debes dejar el `VENDOR_ID` como `0xFEED`. Para el `PRODUCT_ID` debes seleccionar un número que todavía no esté en uso. + +Cambia las líneas de `MANUFACTURER` y `PRODUCT` para reflejar con precisión tu teclado. + +```c +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER Tú +#define PRODUCT mi_teclado_fantastico +``` + +?> Windows y macOS mostrarán el `MANUFACTURER` y `PRODUCT` en la lista de dispositivos USB. `lsusb` en Linux toma estos de la lista mantenida por el [Repositorio de ID USB](http://www.linux-usb.org/usb-ids.html) por defecto. `lsusb -v` mostrará los valores reportados por el dispositivo, y también están presentes en los registros del núcleo después de conectarlo. + +### Configuración de la matriz del teclado + +La siguiente sección del archivo `config.h` trata de la matriz de tu teclado. Lo primero que debes establecer es el tamaño de la matriz. Esto es generalmente, pero no siempre, el mismo número de filas y columnas como la disposición física de las teclas. + +```c +#define MATRIX_ROWS 2 +#define MATRIX_COLS 3 +``` + +Una vez que hayas definido el tamaño de tu matriz, necesitas definir qué pines en tu MCU están conectados a filas y columnas. Para hacerlo simplemente especifica los nombres de esos pines: + +```c +#define MATRIX_ROW_PINS { D0, D5 } +#define MATRIX_COL_PINS { F1, F0, B0 } +#define UNUSED_PINS +``` + +El número de entradas debe ser el mismo que el número que asignaste a `MATRIX_ROWS`, y del mismo modo para `MATRIX_COL_PINS` y `MATRIX_COLS`. No tienes que especificar `UNUSED_PINS`, pero puedes si deseas documentar qué pines están abiertos. + +Finalmente, puedes especificar la dirección en la que apuntan tus diodos. Esto puede ser `COL2ROW` o `ROW2COL`. + +```c +#define DIODE_DIRECTION COL2ROW +``` + +#### Matriz de patas directas +Para configurar un teclado en el que cada interruptor está conectado a un pin y tierra separados en lugar de compartir los pines de fila y columna, usa `DIRECT_PINS`. La asignación define los pines de cada interruptor en filas y columnas, de izquierda a derecha. Debe ajustarse a los tamaños dentro de `MATRIX_ROWS` y `MATRIX_COLS`. Usa `NO_PIN` para rellenar espacios en blanco. Sobreescribe el comportamiento de `DIODE_DIRECTION`, `MATRIX_ROW_PINS` y `MATRIX_COL_PINS`. + +```c +// #define MATRIX_ROW_PINS { D0, D5 } +// #define MATRIX_COL_PINS { F1, F0, B0 } +#define DIRECT_PINS { \ + { F1, E6, B0, B2, B3 }, \ + { F5, F0, B1, B7, D2 }, \ + { F6, F7, C7, D5, D3 }, \ + { B5, C6, B6, NO_PIN, NO_PIN } \ +} +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +//#define DIODE_DIRECTION +``` + +### Configuración de retroiluminación + +QMK soporta retroiluminación en la mayoría de los pines GPIO. Algunos de ellos pueden ser manejados por el MCU en hardware. Para más detalles, consulta la [Documentación de Retroiluminación](feature_backlight.md). + +```c +#define BACKLIGHT_PIN B7 +#define BACKLIGHT_LEVELS 3 +#define BACKLIGHT_BREATHING +#define BREATHING_PERIOD 6 +``` + +### Otras opciones de configuración + +Hay un montón de características que se pueden configurar o ajustar en `config.h`. Debes consultar la página de [Opciones de Configuración](config_options.md) para más detalles. + +## `rules.mk` + +Usa el archivo `rules.mk` para decirle a QMK qué archivos construir y qué características habilitar. Si estás construyendo sobre un atmega32u4 deberías poder dejar mayormente los valores predeterminados. Si estás usando otro MCU es posible que tengas que ajustar algunos parámetros. + +### Opciones MCU + +Estas opciones le indican al sistema de compilación para qué CPU construir. Ten mucho cuidado si cambias cualquiera de estos ajustes. Puedes inutilizar tu teclado. + +```make +MCU = atmega32u4 +F_CPU = 16000000 +ARCH = AVR8 +F_USB = $(F_CPU) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT +``` + +### Gestores de arranque + +El gestor de arranque es una sección especial de tu MCU que te permite actualizar el código almacenado en el MCU. Piensa en ello como una partición de rescate para tu teclado. + +#### Ejemplo de gestor de arranque + +```make +BOOTLOADER = halfkay +``` + +#### Ejemplo de cargador DFU Atmel + +```make +BOOTLOADER = atmel-dfu +``` + +#### Ejemplo de gestor de arranque Pro Micro + +```make +BOOTLOADER = caterina +``` + +### Opciones de construcción + +Hay un serie de características que se pueden activar o desactivar en `rules.mk`. Consulta la página de [Opciones de Configuración](config_options.md#feature-options) para obtener una lista detallada y una descripción. diff --git a/es/hardware_drivers.md b/es/hardware_drivers.md new file mode 100644 index 00000000000..7b74b34b456 --- /dev/null +++ b/es/hardware_drivers.md @@ -0,0 +1,36 @@ +# Controladores de hardware QMK + +QMK se utiliza en un montón de hardware diferente. Mientras que el soporte para los MCUs y las configuraciones de matriz más comunes está integrado, hay una serie de controladores que se pueden añadir para soportar hardware adicional al teclado. Los ejemplos incluyen ratones y otros dispositivos de apuntamiento, extensores de i/o para teclados divididos, modúlos Bluetooth, y pantallas LCD, OLED y TFT. + + + +# Controladores disponibles + +## ProMicro (Solo AVR) + +Soporte para direccionar pines en el ProMicro por su nombre Arduino en lugar de su nombre AVR. Esto necesita ser mejor documentado. Si estás tratando de hacer esto y leer el código no ayuda por favor [abre una issue](https://github.com/qmk/qmk_firmware/issues/new) y podemos ayudarte por el proceso. + +## Controlador OLED SSD1306 + +Soporte para pantallas OLED basadas en SSD1306. Para obtener más información consulta la página de [Característica de Controlador OLED](feature_oled_driver.md). + +## uGFX + +Puedes hacer uso de uGFX dentro de QMK para manejar LCDs de caracteres y gráficos, matrices de LED, OLED, TFT, y otras tecnologías de visualización. Esto necesita ser mejor documentado. Si estás tratando de hacer esto y leer el código no ayuda por favor [abre una issue](https://github.com/qmk/qmk_firmware/issues/new) y podemos ayudarte por el proceso. + +## WS2812 (Solo AVR) + +Soporte para LEDs WS2811/WS2812{a,b,c}. Para obtener más información consulta la página de [Luz RGB](feature_rgblight.md). + +## IS31FL3731 + +Soporte para hasta 2 controladores. Cada controlador implementa 2 matrices charlieplex para direccionar LEDs individualmente usando I2C. Esto permite hasta 144 LEDs del mismo color o 32 LEDs RGB. Para obtener más información sobre cómo configurar el controlador, consulta la página de [Matriz RGB](feature_rgb_matrix.md). + +## IS31FL3733 + +Soporte para hasta un solo controlador con espacio para expansión. Cada controlador puede controlar 192 LEDs individuales o 64 LEDs RGB. Para obtener más información sobre cómo configurar el controlador, consulta la página de [Matriz RGB](feature_rgb_matrix.md). + diff --git a/es/hardware_keyboard_guidelines.md b/es/hardware_keyboard_guidelines.md new file mode 100644 index 00000000000..2cde2b39fb7 --- /dev/null +++ b/es/hardware_keyboard_guidelines.md @@ -0,0 +1,149 @@ +# Pautas del teclado QMK + +Desde sus inicios, QMK ha crecido a pasos agigantados gracias a personas como tú que contribuyes a la creación y mantenimiento de nuestros teclados comunitarios. A medida que hemos crecido hemos descubierto algunos patrones que funcionan bien, y pedimos que te ajustes a ellos para que sea más fácil para que otras personas se beneficien de tu duro trabajo. + + +## Nombrar tu Teclado/Proyecto + +Todos los nombres de teclado están en minúsculas, consistiendo sólo de letras, números y guiones bajos (`_`). Los nombres no pueden comenzar con un guión bajo. La barra de desplazamiento (`/`) se utiliza como un carácter de separación de subcarpetas. + +Los nombres `test`, `keyboard`, y `all` están reservados para las órdenes de make y no pueden ser usados como un nombre de teclado o subcarpeta. + +Ejemplos Válidos: + +* `412_64` +* `chimera_ortho` +* `clueboard/66/rev3` +* `planck` +* `v60_type_r` + +## Subcarpetas + +QMK utiliza subcarpetas tanto para organización como para compartir código entre las revisiones del mismo teclado. Puedes anidar carpetas hasta 4 niveles de profundidad: + + qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4 + +Si una subcarpeta tiene un archivo `rules.mk` será considerado un teclado compilable. Estará disponible en el configurador de QMK y se probará con `make all`. Si estás utilizando una carpeta para organizar varios teclados del mismo fabricante no debes tener un archivo `rules.mk`. + +Ejemplo: + +Clueboard utiliza subcarpetas para ambos propósitos: organización y revisiones de teclado. + +* [`qmk_firmware`](https://github.com/qmk/qmk_firmware/tree/master) + * [`keyboards`](https://github.com/qmk/qmk_firmware/tree/master/keyboards) + * [`clueboard`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard) ← This is the organization folder, there's no `rules.mk` file + * [`60`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/60) ← This is a compilable keyboard, it has a `rules.mk` file + * [`66`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66) ← This is also compilable- it uses `DEFAULT_FOLDER` to specify `rev3` as the default revision + * [`rev1`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev1) ← compilable: `make clueboard/66/rev1` + * [`rev2`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev2) ← compilable: `make clueboard/66/rev2` + * [`rev3`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev3) ← compilable: `make clueboard/66/rev3` or `make clueboard/66` + +## Estructura de carpetas de teclado + +Su teclado debe estar ubicado en `qmk_firm cuidada/keyboards/` y el nombre de la carpeta debe ser el nombre de su teclado como se describe en la sección anterior. Dentro de esta carpeta debe haber varios archivos: + +* `readme.md` +* `info.json` +* `config.h` +* `rules.mk` +* `.c` +* `.h` + +### `readme.md` + +Todos los proyectos necesitan tener un archivo `readme.md` que explica lo que es el teclado, quién lo hizo y dónde está disponible. Si es aplicable, también debe contener enlaces a más información, como el sitio web del fabricante. Por favor, sigue la [plantilla publicada](documentation_templates.md#keyboard-readmemd-template). + +### `info.json` + +Este archivo es utilizado por la [API de QMK](https://github.com/qmk/qmk_api). Contiene la información que [configurador de QMK](https://config.qmk.fm/) necesita mostrar en una representación de su teclado. También puede establecer metadatos aquí. Para más información, consulta la [página de referencia](reference_info_json.md). + +### `config.h` + +Todos los proyectos necesitan tener un archivo `config.h` que establece cosas como el tamaño de la matriz, nombre del producto, USB VID/PID, descripción y otros ajustes. En general, usa este archivo para establecer la información esencial y los valores predeterminados para tu teclado que siempre funcionarán. + +### `rules.mk` + +La presencia de este archivo indica que la carpeta es un destino de teclado y se puede utilizar en las órdenes `make`. Aquí es donde estableces el entorno de compilación para tu teclado y configuras el conjunto predeterminado de características. + +### `` + +Aquí es donde escribirás código personalizado para tu teclado. Típicamente escribirás código para inicializar e interactuar con el hardware de tu teclado. Si tu teclado se compone de sólo una matriz de teclas sin LEDs, altavoces u otro hardware auxiliar este archivo puede estar en blanco. + +Las funciones siguientes se definen típicamente en este archivo: + +* `void matrix_init_kb(void)` +* `void matrix_scan_kb(void)` +* `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* `void led_set_kb(uint8_t usb_led)` + +### `` + +Este archivo se utiliza para definir la matriz para tu teclado. Debes definir al menos un macro de C que traduce una serie en una matriz que representa la matriz de interruptor físico para tu teclado. Si es posible construir tu teclado con múltiples diseños debes definir macros adicionales. + +Si solo tienes un diseño debes llamar a esta macro `LAYOUT`. + +Al definir diseños múltiples debes tener un diseño base, llamado `LAYOUT_all`, que soporte todas las posibles posiciones de switch en tu matriz, incluso si ese diseño es imposible de construir físicamente. Esta es la macro que deberías usar en tu keymap `predeterminado`. Debes tener keymaps adicionales llamados `default_ término layout>` que usen tus otras macros de diseño. Esto hará que sea más fácil para las personas utilizar los diseños que defines. + +Los nombres de las macros de diseño son completamente minúsculas, excepto por la palabra `LAYOUT` en el frente. + +Por ejemplo, si tienes un PCB de 60% que soporta ANSI e ISO podría definir los siguientes diseños y keymaps: + +| Nombre de diseño | Nombre de keymap | Descripción | +|-------------|-------------|-------------| +| LAYOUT_all | default | Un diseño que soporta tanto ISO como ANSI | +| LAYOUT_ansi | default_ansi | Un diseño ANSI | +| LAYOUT_iso | default_iso | Un diseño ISO | + +## Archivos de Imagen/Hardware + +En un esfuerzo por mantener el tamaño de repo abajo ya no estamos aceptando archivos binarios de cualquier formato, con pocas excepciones. Alojarlos en otro lugar (por ejemplo ) y enlazarlos en el `readme.md` es preferible. + +Para archivos de hardware (tales como placas, casos, pcb) puedes contribuir a [qmk.fm repo](https://github.com/qmk/qmk.fm) y estarán disponibles en [qmk.fm](http://qmk.fm). Archivos descargables se almacenan en `//` (nombre sigue el mismo formato que el anterior), se sirven en `http://qmk.fm//`, y se generan páginas de `/_pages//` que se sirven en la misma ubicación (Los archivos .md se generan en archivos .html mediante Jekyll). Echa un vistazo a la carpeta `lets_split` para ver un ejemplo. + +## Predeterminados de teclado + +Dada la cantidad de funcionalidad que expone QMK, es muy fácil confundir a los nuevos usuarios. Al armar el firmware predeterminado para tu teclado, te recomendamos limitar tus funciones y opciones habilitadas al conjunto mínimo necesario para soportar tu hardware. A continuación se formulan recomendaciones sobre características específicas. + +### Bootmagic y Command + +[Bootmagic](feature_bootmagic.md) and [Command](feature_command.md) son dos características relacionadas que permiten a un usuario controlar su teclado de manera no obvia. Te recomendamos que piense largo y tendido acerca de si vas a habilitar cualquiera de las características, y cómo vas a exponer esta funcionalidad. Tengas en cuenta que los usuarios que quieren esta funcionalidad puede habilitarla en sus keymaps personales sin afectar a todos los usuarios novatos que pueden estar usando tu teclado como su primera tarjeta programable. + +De lejos el problema más común con el que se encuentran los nuevos usuarios es la activación accidental de Bootmagic mientras están conectando su teclado. Están sosteniendo el teclado por la parte inferior, presionando sin saberlo en alt y barra espaciadora, y luego se dan cuenta de que estas teclas han sido intercambiadas en ellos. Recomendamos dejar esta característica deshabilitada de forma predeterminada, pero si la activas consideres establecer la opción `BOOTMAGIC_KEY_SALT` a una tecla que es difícil de presionar al conectar el teclado. + +Si tu teclado no tiene 2 teclas de cambio debes proporcionar un predeterminado de trabajo para `IS_COMMAND`, incluso cuando haya definido `COMMAND_ENABLE = no`. Esto dará a sus usuarios un valor predeterminado para ajustarse a si lo hacen enable Command. + +## Programación de teclado personalizado + +Como se documenta en [Funcionalidad de Adaptación](custom_quantum_functions.md) puedes definir funciones personalizadas para tu teclado. Por favor, tengas en cuenta que sus usuarios pueden querer personalizar ese comportamiento así, y hacer que sea posible para que puedan hacer eso. Si está proporcionando una función personalizada, por ejemplo `process_record_kb()`, asegúrese de que su función también llame a la versión` `_user()` de la llamada. También debes tener en cuenta el valor de retorno de la versión `_user()`, y ejecutar sólo tu código personalizado si el usuario devuelve `true`. + +## Proyectos Sin Producción/Conectados A Mano + +Estamos encantados de aceptar cualquier proyecto que utilice QMK, incluidos los prototipos y los cableados de mano, pero tenemos una carpeta `/keyboards/handwired/` separada para ellos, por lo que la carpeta `/keyboards/` principal no se llena. Si un proyecto prototipo se convierte en un proyecto de producción en algún momento en el futuro, ¡estaremos encantados de moverlo a la carpeta `/keyboards/` principal! + +## Advertencias como errores + +Al desarrollar su teclado, tengas en cuenta que todas las advertencias serán tratadas como errores - estas pequeñas advertencias pueden acumularse y causar errores más grandes en el camino (y pierdan es generalmente una mala práctica). + +## Derechos de autor + +Si estás adaptando la configuración de tu teclado de otro proyecto, pero no utilizando el mismo código, asegúrese de actualizar la cabecera de derechos de autor en la parte superior de los archivos para mostrar tu nombre, en este formato: + + Copyright 2017 Tu nombre + +Si estás modificando el código de otra persona y sólo ha hecho cambios triviales debes dejar su nombre en la declaración de derechos de autor. Si has hecho un trabajo significativo en el archivo debe agregar tu nombre a la de ellos, así: + + Copyright 2017 Su nombre Tu nombre + +El año debe ser el primer año en que se crea el archivo. Si el trabajo se hizo a ese archivo en años posteriores puedes reflejar que mediante la adición del segundo año a la primera, como así: + + Copyright 2015-2017 Tu nombre + +## Licencia + +El núcleo de QMC está licenciado bajo la [GNU General Public License](https://www.gnu.org/licenses/licenses.en.html). Si estás enviando binarios para los procesadores AVR puedes elegir cualquiera [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) o [GPLv3](https://www.gnu.org/licenses/gpl.html). Si estás enviando binarios para ARM procesadores debes elegir [GPL Versión 3](https://www.gnu.org/licenses/gpl.html) para cumplir con los [ChibiOS](http://www.chibios.org) licencia GPLv3. + +Si tu teclado hace uso de la [uGFX](https://gfx.io) características dentro de QMK debes cumplir con la [Licencia de uGFX](https://ugfx.io/license.html), que requiere una licencia comercial separada antes de vender un dispositivo que contiene uGFX. + +## Detalles técnicos + +Si estás buscando más información sobre cómo hacer que su teclado funcione con QMK, [echa un vistazo a la sección hardware](hardware.md)! diff --git a/es/newbs.md b/es/newbs.md new file mode 100644 index 00000000000..ebb4b6ac2d1 --- /dev/null +++ b/es/newbs.md @@ -0,0 +1,23 @@ +# La guía completa de QMK para novatos + +QMK es un poderoso firmware Open Source para tu teclado mecánico. Puedes utilizar QMK para personalizar tu teclado en maneras a la vez simples y potentes. Gente de todos los niveles de habilidad, desde completos novatos hasta expertos programadores, han utilizado con éxito QMK para personalizar sus teclados. Esta guía te ayudará a hacer lo mismo, sin importar tu nivel de habilidad. + +¿No estás seguro de si tu teclado puede ejecutar QMK? Si es un teclado mecánico construido por ti mismo probablemente puedas. Damos soporte a [gran número de placas de hobbistas](http://qmk.fm/keyboards/), e incluso si tu teclado actual no pudiera ejecutar QMK no deberías tener problemas encontrando uno que cumpliera tus necesidades. + +## Visión general + +Hay 7 secciones principales en esta guía: + +* [Empezando](newbs_getting_started.md) +* [Construyendo tu primer firmware](newbs_building_firmware.md) +* [Construyendo tu primer firmware usando la GUI](newbs_building_firmware_configurator.md) +* [Flasheando el firmware](newbs_flashing.md) +* [Testeando y depurando](newbs_testing_debugging.md) +* [Mejores práticas](newbs_best_practices.md) +* [Recursos de aprendizaje](newbs_learn_more_resources.md) + +Esta guía está enfocada en ayudar a alguien que nunca ha compilado software con anterioridad. Toma decisiones y hace recomendaciones teniendo en cuenta este punto de vista. Hay métodos alternativos para muchos de estos procedimientos, y soportamos la mayoría de esas alternativas. Si tienes alguna duda sobre cómo llevar a cabo una tarea nos puedes [preguntar para que te guiemos](getting_started_getting_help.md). + +## Recursos adicionales + +* [Blog de Básicos de Thomas Baart's QMK](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – Un blog creado por un usuario que cubre lo básico sobre cómo usar el firmware QMK Firmware, visto desde la perspectiva de un usuario nuevo. diff --git a/es/newbs_best_practices.md b/es/newbs_best_practices.md new file mode 100644 index 00000000000..2f72eff788c --- /dev/null +++ b/es/newbs_best_practices.md @@ -0,0 +1,159 @@ +# Mejores prácticas + +## O, "Cómo aprendí a dejar de preocuparme y amarle a Git." + +Este documento procura instruir a los novatos en las mejores prácticas para tener una experiencia más fácil en contribuir a QMK. Te guiaremos por el proceso de contribuir a QMK, explicando algunas maneras de hacerlo más fácilmente, y luego romperemos algunas cosas para enseñarte cómo arreglarlas. + +En este documento suponemos un par de cosas: + +1. Tienes una cuenta de GitHub, y has hecho un [fork del repo qmk_firmware](getting_started_github.md) en tu cuenta. +2. Has [configurado tu entorno de desarrollo](newbs_getting_started.md?id=environment-setup). + + +## La rama master de tu fork: Actualizar a menudo, nunca commit + +Se recomienda que para desarrollo con QMK, lo que sea que estés haciendo, mantener tu rama `master` actualizada, pero **nunca** commit en ella. Mejor, haz todos tus cambios en una rama de desarrollo y manda pull requests de tus ramas mientras programas. + +Para evitar los conflictos de merge — cuando dos o más usuarios han editado la misma parte de un archivo al mismo tiempo — mantén tu rama `master` actualizada, y empieza desarrollo nuevo creando una nueva rama. + +### Actualizando tu rama master + +Para mantener tu rama `master` actualizada, se recomienda agregar el repository ("repo") de Firmware QMK como un repo remoto en git. Para hacer esto, abre tu interfaz de línea de mandatos y ingresa: +``` +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +Para verificar que el repo ha sido agregado, ejecuta `git remote -v`, y lo siguiente debe aparecer: + +``` +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +Ya que has hecho esto, puedes buscar actualizaciones del repo ejecutando `git fetch upstream`. Esto busca las ramas y etiquetas — juntos conocidos como "refs" — del repo QMK, que ahora tiene el apodo `upstream`. Ahora podemos comparar los archivos en nuestro fork `origin` con los de QMK. + +Para actualizar la rama master de tu fork, ejecuta lo siguiente, pulsando Intro después de cada línea: + +``` +git checkout master +git fetch upstream +git pull upstream master +git push origin master +``` + +Esto te coloca en tu rama master, busca los refs del repo de QMK, descarga la rama `master` actual a tu computadora, y después lo sube a tu fork. + +### Hacer cambios + +Para hacer cambios, crea una nueva rama ejecutando: + +``` +git checkout -b dev_branch +git push --set-upstream origin dev_branch +``` + +Esto crea una nueva rama llamada `dev_branch`, te coloca en ella, y después guarda la nueva rama a tu fork. El parámetro `--set-upstream` le dice a git que use tu fork y la rama `dev_branch` cada vez que uses `git push` o `git pull` en esta rama. Solo necesitas usarlo la primera que que subes cambios; ya después, puedes usar `git push` o `git pull`, sin usar los demás parámetros. + +!> Con `git push`, puedes usar `-u` en vez de `--set-upstream` — `-u` es un alias de `--set-upstream`. + +Puedes nombrar tu rama casi cualquier cosa, pero se recomienda ponerle algo con relación a los cambios que vas a hacer. + +Por defecto `git checkout -b` se basará tu nueva rama en la rama en la cual estás actualmente. Puedes basar tu rama en otra rama existente agregando el nombre de la rama al comando: + +``` +git checkout -b dev_branch master +``` + +Ahora que tienes una rama development, abre tu editor de texto y haz los cambios que quieres. Se recomienda hacer varios commits pequeños a tu rama; de este modo cualquier cambio que causa problemas puede ser rastreado y deshecho si fuera necesario. Para hacer tus cambios, edita y guarda los archivos que necesitas actualizar, agrégalos al *staging area* de Git, y luego haz un commit a tu rama: + +``` +git add path/to/updated_file +git commit -m "My commit message." +``` +`git add` agrega los archivos que han sido cambiados al *staging area* de Git, lo cual es la "zona de preparación"de Git. Este contiene los cambios que vas a *commit* usando `git commit`, que guarda los cambios en el repo. Usa un mensaje de commit descriptivo para que puedas saber que ha cambiado fácilmente. + +!> Si has cambiado muchos archivos, pero todos los archivos son parte del mismo cambio, puedes usar `git add .` para agregar todos los archivos cambiados que están en tu directiro actual, en vez de agregar cada archivo manualmente. + +### Publicar tus cambios + +El útimo paso es subir tus cambios a tu fork. Para hacerlo, ejecuta `git push`. Ahora Git publicará el estado actual de `dev_branch` a tu fork. + + +## Resolver los conflictos del merge + +A veces cuando el trabajo en una rama tarda mucho tiempo en completarse, los cambios que han sido hechos por otros chocan con los cambios que has hecho en tu rama cuando abres un pull request. Esto se llama un *merge conflict*, y es algo que ocurre cuando varias personas editan las mismas partes de los mismos archivos. + +### Rebase tus cambios + +Un *rebase* es la manera de Git de tomar los cambios que se aplicaron en un punto, deshacerlos, y aplicar estos mismos cambios en otro punto. En el caso de un conflicto de merge, puedes hacer un rebase de tu rama para recoger los cambios que has hecho. + +Para empezar, ejecuta lo siguiente: + +``` +git fetch upstream +git rev-list --left-right --count HEAD...upstream/master +``` + +El comando `git rev-list` ejecutado aquí muestra el número de commits que difieren entre la rama actual y la rama master de QMK. Ejecutamos `git fetch` primero para asegurarnos de que tenemos los refs que representan es estado actual del repo upstream. El output del comando `git rev-list` muestra dos números: + +``` +$ git rev-list --left-right --count HEAD...upstream/master +7 35 +``` + +El primer número representa el número de commits en la rama actual desde que fue creada, y el segundo número es el número de commits hecho a `upstream/master` desde que la rama actual fue creada, o sea los cambios que no están registrados en la rama actual. + +Ahora que sabemos el estado actual de la rama actual y el del repo upstream, podemos empezar una operación rebase: + +``` +git rebase upstream/master +``` +Esto le dice a Git que deshaga los commits en la rama actual, y después los re-aplica en la rama master de QMK. + +``` +$ git rebase upstream/master +First, rewinding head to replay your work on top of it... +Applying: Commit #1 +Using index info to reconstruct a base tree... +M conflicting_file_1.txt +Falling back to patching base and 3-way merge... +Auto-merging conflicting_file_1.txt +CONFLICT (content): Merge conflict in conflicting_file_1.txt +error: Failed to merge in the changes. +hint: Use 'git am --show-current-patch' to see the failed patch +Patch failed at 0001 Commit #1 + +Resolve all conflicts manually, mark them as resolved with +"git add/rm ", then run "git rebase --continue". +You can instead skip this commit: run "git rebase --skip". +To abort and get back to the state before "git rebase", run "git rebase --abort". +``` + +Esto nos dice que tenemos un conflicto de merge, y nos dice el nombre del archivo con el conflict. Abre el archivo en tu editor de texto, y en alguna parte del archivo verás algo así: + +``` +<<<<<<< HEAD +

For help with any issues, email us at support@webhost.us.

+======= +

Need help? Email support@webhost.us.

+>>>>>>> Commit #1 +``` +La línea `<<<<<<< HEAD` marca el principio de un conflicto de merge, y la línea `>>>>>>> Commit #1` marca el final, con las secciones de conflicto separadas por `=======`. La parte del lado `HEAD` is de la versión de QMK master del archivo, y la parte marcada con el mensaje de commit es de la rama actual. + +Ya que Git rastrea *cambios de archivos* en vez del contenido de los archivos directamente, si Git no puede encontrar el texto que estaba en el archivo antes del último commit, no sabrá cómo editar el archivo. El editar el archivo de nuevo resolverá este conflicto. Haz tus cambios, y guarda el archivo. + +``` +

Need help? Email support@webhost.us.

+``` + +Ahora ejecuta: + +``` +git add conflicting_file_1.txt +git rebase --continue +``` + +Git registra los cambios al archivo con conflictos, y sigue aplicando los commits de nuestra rama hasta llegar al final. diff --git a/es/newbs_building_firmware.md b/es/newbs_building_firmware.md new file mode 100644 index 00000000000..ff9873c785e --- /dev/null +++ b/es/newbs_building_firmware.md @@ -0,0 +1,81 @@ +# Construyendo tu primer firmware + +Ahora que has configurado tu entorno de construcción estas listo para empezar a construir firmwares personalizados. Para esta sección de la guía alternaremos entre 3 programas - tu gestor de ficheros, tu editor de texto , y tu ventana de terminal. Manten los 3 abiertos hasta que hayas acabado y estés contento con el firmware de tu teclado. + +Si has cerrado y reabierto la ventana de tu terminal después de seguir el primero paso de esta guía, no olvides hacer `cd qmk_firmware` para que tu terminal esté en el directorio correcto. + +## Navega a tu carpeta de keymaps + +Comienza navegando a la carpeta `keymaps` correspondiente a tu teclado. + +?> Si estás en macOS o Windows hay comandos que puedes utilizar fácilmente para abrir la carpeta keymaps. + +?> macOS: + + abre keyboards//keymaps + +?> Windows: + + inicia .\\keyboards\\\\keymaps + +## Crea una copia del keymap `default` + +Una vez que tengas la carpeta `keymaps` abierta querrás crear una copia de la carpeta `default`. Recomendamos encarecidamente que nombres la carpeta igual que tu nombre de usuario de GitHub, pero puedes utilizar el nombre que quieras siempre que contenga sólo letras en minúscula, números y el caracter de guión bajo. + +Para automatizar el proceso, también tienes la opción de ejecutar el script `new_keymap.sh`. + +Navega a la carpeta `qmk_firmware/util` e introduce lo siguiente: + +``` +./new_keymap.sh +``` + +Por ejemplo, para un usuario llamado John, intentando hacer un keymap nuevo para el 1up60hse, tendría que teclear + +``` +./new_keymap.sh 1upkeyboards/1up60hse john +``` + +## Abre `keymap.c` con tu editor de texto favorito + +Abre tu `keymap.c`. Dentro de este fichero encontrarás la estructura que controla cómo se comporta tu teclado. En lo alto de `keymap.c` puede haber distintos defines y enums que hacen el keymap más fácil de leer. Continuando por abajo encontrarás una línea con este aspecto: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +Esta línea indica el comienzo del listado de Capas. Debajo encontrarás líneas que contienen o bien `LAYOUT` o `KEYMAP`, y estas líneas indican el comienzo de una capa. Debajo de esa línea está la lista de teclas que pertenecen a esa capa concreta. + +!> Cuando estés editando tu fichero de keymap ten cuidado con no añadir ni eliminar ninguna coma. Si lo haces el firmware dejará de compilar y puede no ser fácil averiguar dónde está la coma faltante o sobrante. + +## Personaliza el Layout a tu gusto + +Cómo completar esta paso depende enteramente de ti. Haz ese pequeño cambio que querías o rehaz completamente todo. Puedes eliminar capas si no las necesitas todas, o añadir nuevas hasta un total de 32. Comprueba la siguiente documentación para descubrir qué es lo que puedes definir aquí: + +* [Keycodes](keycodes.md) +* [Características](features.md) +* [Preguntas frecuentes](faq.md) + +?> Mientras estás descubriendo cómo funcionan los keymaps, haz pequeños cambios. Cambios mayores pueden hacer difícil la depuración de problemas que puedan aparecer. + +## Construye tu firmware + +Cuando los cambios a tu keymap están completos necesitarás construir el firmware. Para hacerlo vuelve a la ventana de tu terminal y ejecuta el siguiente comando: + + make : + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un planck rev5, utilizarás el siguiente comando: + + make planck/rev5:xyverz + +Mientras compila, recibirás un montón de información de salida en la pantalla informándote de qué ficheros están siendo compilados. Debería acabar con una información similar a esta: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex [OK] + * File size is fine - 18392/28672 +``` + +## Flashea tu firmware + +Continua con [Flasheando el firmware](newbs_flashing.md) para aprender cómo escribir tu firmware nuevo en tu teclado. diff --git a/es/newbs_building_firmware_configurator.md b/es/newbs_building_firmware_configurator.md new file mode 100644 index 00000000000..60d67f5fa4f --- /dev/null +++ b/es/newbs_building_firmware_configurator.md @@ -0,0 +1,105 @@ +# Configurador QMK + +El [Configurador QMK](https://config.qmk.fm) es un entorno gráfico online que genera ficheros hexadecimales de Firmware QMK. + +?> **Por favor sigue estos pasos en orden.** + +Ve el [Video tutorial](https://www.youtube.com/watch?v=-imgglzDMdY) + +El Configurador QMK functiona mejor con Chrome/Firefox. + + +!> **Ficheros de otras herramientas como KLE, o kbfirmware no serán compatibles con el Configurador QMK. No las cargues, no las importes. El configurador Configurador QMK es una herramienta DIFERENTE. ** + +## Seleccionando tu teclado + +Haz click en el desplegable y selecciona el teclado para el que quieres crear el keymap. + +?> Si tu teclado tiene varias versiones, asegúrate de que seleccionas la correcta.** + +Lo diré otra vez porque es importante + +!> **ASEGÚRATE DE QUE SELECCIONAS LA VERSIÓN CORRECTA!** + +Si se ha anunciado que tu teclado funciona con QMK pero no está en la lista, es probable que un desarrollador no se haya encargado de él aún o que todavía no hemos tenido la oportunidad de incluirlo. Abre un issue en [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) solicitando soportar ese teclado un particular, si no hay un [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) activo para ello. Hay también teclados que funcionan con QMK que están en las cuentas de GitHub de sus manufacturantes. Acuérdate de comprobar esto también. + +## Eligiendo el layout de tu teclado + +Elige el layout que mejor represente el keymap que quieres crear. Algunos teclados no tienen suficientes layouts o layouts correctos definidos aún. Serán soportados en el futuro. + +## Nombre del keymap + +Llama a este keymap como quieras. + +?> Si estás teniendo problemas para compilar, puede merecer la pena probar un cambio de nombre, ya que puede que ya exista en el repositorio de QMK Firmware. + +## Creando Tu keymap + +La adición de keycodes se puede hacer de 3 maneras. +1. Arrastrando y soltando +2. Clickando en un hueco vacío en el layout y haciendo click en el keycode que deseas +3. Clickando en un hueco vacío en el layout, presionando la tecla física en tu teclado. + +Mueve el puntero de tu ratón sobre una tecla y un pequeño extracto te dirá que es lo que hace la tecla. Para una descripción más detallada por favor, mira + +[Referencia básica de keycodes](https://docs.qmk.fm/#/keycodes_basic) +[Referencia avanzada de keycodes](https://docs.qmk.fm/#/feature_advanced_keycodes) + +En el caso de que no puedas encontrar un layout que suporte tu keymap, por ejemplo, tres huecos para la barra espaciadora, dos huecos para el retroceso o dos huecos para shift etc etc, rellènalos TODOS. + +### Ejemplo: + +3 huecos para barra espaciadora: Rellena TODOS con barra espaciadora + +2 huecos para retroceso: Rellena AMBOS con retroceso + +2 huecos para el shift derecho: Rellena AMBOS con shift derecho + +1 hueco para el shift izquierdo y 1 hueco para soporte iso: Rellena ambos con el shift izquierdo + +5 huecos , pero sólo 4 teclas: Intuye y comprueba o pregunta a alguien que lo haya hecho anteriormente. + +## Guardando tu keymap para ediciones futuras + +Cuando estés satisfecho con un teclado o quieres trabajar en el después, pulsa el botón `Exportar Keymap`. Guardára tu keymap con el nombre que elijas seguido de .json. + +Entonces podrás cargar este fichero .json en el futuro pulsando el botón `Importar Keymap`. + +!> **PRECAUCIÓN:** No es el mismo tipo de fichero .json usado en kbfirmware.com ni ninguna otra herramienta. Si intentas utilizar un fichero .json de alguna de estas herramientas con el Configurador QMK, existe la posibilidad de que tu teclado **explote**. + +## Generando tu fichero de firmware + +Pulsa el botón verde `Compilar`. + +Cuando la compilación haya acabado, podrás presionar el botón verde `Descargar Firmware`. + +## Flasheando tu teclado + +Por favor, dirígete a la sección de [Flashear firmware](newbs_flashing.md) + +## Problemas comunes + +#### Mi fichero .json no funciona + +Si el fichero .json fue generado con el Configurador QMK, enhorabuena, has dado con un bug. Abre una issue en [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) + +Si no....cómo no viste el mensaje en negrita que puse arriba diciendo que no hay que utilizar otros ficheros .json? + +#### Hay espacios extra en mi layout ¿Qué hago? + +Si te refieres a tener tres espacios para la barra espaciadora, la mejor decisión es rellenar los tres con la barra espaciadora. También se puede hacer lo mismo con las teclas retroceso y las de shift + +#### Para qué sirve el keycode....... + +Por favor, mira + +[Referencia básica de keycodes](https://docs.qmk.fm/#/keycodes_basic) +[Referencia avanzada de keycodes](https://docs.qmk.fm/#/feature_advanced_keycodes) + +#### No compila + +Por favor, revisa las otras capas de tu keymap para asegurarte de que no hay teclas aleatorias presentes. + +## Problemas y bugs + +Siempre aceptamos peticiones de clientes y reportes de bug. Por favor, indícalos en [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) diff --git a/es/newbs_flashing.md b/es/newbs_flashing.md new file mode 100644 index 00000000000..066715c4830 --- /dev/null +++ b/es/newbs_flashing.md @@ -0,0 +1,351 @@ +# Flasheando tu teclado + +Ahora que has construido tu fichero de firmware personalizado querrás flashear tu teclado. + +## Flasheando tu teclado con QMK Toolbox + +La manera más simple de flashear tu teclado sería con [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases). + +De todos modos, QMK Toolbox actualmente sólo está disponible para Windows y macOS. Si estás usando Linux (o sólo quisieras flashear el firmware desde la línea de comandos), tendrás que utilizar el [método indicado abajo](newbs_flashing.md#flash-your-keyboard-from-the-command-line). + +### Cargar el fichero en QMK Toolbox + +Empieza abriendo la aplicación QMK Toolbox. Tendrás que buscar el fichero de firmware usando Finder o Explorer. El firmware de teclado puede estar en uno de estos dos formatos- `.hex` o `.bin`. QMK intenta copiar el apropiado para tu teclado en el fichero raíz `qmk_firmware`. + +?> Si tu estás on Windows o macOS hay comandos que puedes usar para abrir fácilmente la carpeta del firmware actual en Explorer o Finder. + +?> Windows: + + start . + +?> macOS: + + open . + +El fichero de firmware sempre sigue el siguiente formato de nombre: + + _.{bin,hex} + +Por ejemplo, un `plank/rev5` con un keymap `default` tendrá este nombre de fichero: + + planck_rev5_default.hex + +Una vez que hayas localizado el fichero de tu firmware arrástralo a la caja "Fichero local" en QMK Toolbox, o haz click en "Abrir" y navega allí donde tengas almacenado tu fichero de firmware. + +### Pon tu teclado en modo DFU (Bootloader) + +Para poder flashear tu firmware personalizado tienes que poner tu teclado en un modo especial que permite flasheado. Cuando está en este modo no podrás teclear o utilizarlo para ninguna otra cosa. Es muy importante que no desconectes tu teclado, de lo contrario interrumpirás el proceso de flasheo mientras el firmware se está escribiendo. + +Diferentes teclados tienen diferentes maneras de entrar en este modo especial. Si tu PCB actualmente ejecuta QMK o TMK y no has recibido instrucciones específicas, intenta los siguientes pasos en orden: + +* Manten pulsadas ambas teclas shift y pulsa `Pause` +* Manten pulsadas ambas teclas shift y pulsa `B` +* Desconecta tu teclado, mantén pulsada la barra espaciadora y `B` al mismo tiempo, conecta tu teclado y espera un segundo antes de dejar de pulsar las teclas +* Pulsa el botón físico `RESET` situado en el fondo de la PCB +* Localiza los pines en la PCB etiquetados on `BOOT0` o `RESET`, puentea estos dos juntos cuando enchufes la PCB + +Si has tenido éxito verás un mensaje similar a este en QMK Toolbox: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +``` + +### Flashea tu teclado + +Haz click en el botón `Flash` de QMK Toolbox. Verás una información de salida similar a esta: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset + +*** DFU device disconnected +*** Clueboard - Clueboard 66% HotSwap connected -- 0xC1ED:0x2390 +``` + +## Flashea tu teclado desde la línea de comandos + +Lo primero que tienes que saber es qué bootloader utiliza tu teclado. Hay cuatro bootloaders pincipales que se usan habitualmente . Pro-Micro y sus clones usan CATERINA, Teensy's usa Halfkay, las placas OLKB usan QMK-DFU, y otros chips atmega32u4 usan DFU. + +Puedes encontrar más información sobre bootloaders en la página [Instrucciones de flasheado e información de Bootloader](flashing.md). + +Si sabes qué bootloader estás usando, en el momento de compilar el firmware, podrás añadir algún texto extra al comando `make` para automatizar el proceso de flasheado. + +### DFU + +Para eo bootloader DFU, cuando estés listo para compilar y flashear tu firmware, abre tu ventana de terminal y ejecuta el siguiente comando de construcción: + + make ::dfu + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un planck rev5, utilizarás este comando: + + make planck/rev5:xyverz:dfu + +Una vez que finalice de compilar, deberá aparecer lo siguiente: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex + * File size is fine - 18574/28672 + ``` + +Después de llegar a este punto, el script de construcción buscará el bootloader DFU cada 5 segundos. Repetirá lo siguiente hasta que se encuentre el dispositivo o lo canceles: + + dfu-programmer: no device present. + Error: Bootloader not found. Trying again in 5s. + +Una vez haya hecho esto, tendrás que reiniciar el controlador. Debería mostrar una información de salida similar a esta: + +``` +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset +``` + +?> Si tienes problemas con esto- del estilo de `dfu-programmer: no device present` - por favor consulta las [Preguntas frecuentes de construcción](faq_build.md). + +#### Comandos DFU + +Hay un número de comandos DFU que puedes usar para flashear firmware a un dispositivo DFU: + +* `:dfu` - Esta es la opción normal y espera hasta que un dispositivo DFU esté disponible, entonces flashea el firmware. Esperará reintentando cada 5 segundos, para ver si un dispositivo DFU ha aparecido. +* `:dfu-ee` - Esta flashea un fichero `eep` en vez del hex normal. Esto no es lo común. +* `:dfu-split-left` - Esta flashea el firmware normal, igual que la opción por defecto (`:dfu`). Sin embargo, también flashea el fichero EEPROM "Lado Izquierdo" para teclados divididos. _Esto es ideal para los ficheros divididos basados en Elite C._ +* `:dfu-split-right` - Esto flashea el firmware normal, igual que la opción por defecto (`:dfu`). Sin embargo, también flashea el fichero EEPROM "Lado Derecho" para teclados divididos. _Esto es ideal para los ficheros divididos basados en Elite C._ + + +### Caterina + +Para placas Arduino y sus clones (como la SparkFun ProMicro), cuando estés listo para compilar y flashear tu firmware, abre tu ventana de terminal y ejecuta el siguiente comando de construcción: + + make ::avrdude + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un Lets Split rev2, usarás este comando: + + make lets_split/rev2:xyverz:avrdude + +Una vez que finalice de compilar, deberá aparecer lo siguiente: + +``` +Linking: .build/lets_split_rev2_xyverz.elf [OK] +Creating load file for flashing: .build/lets_split_rev2_xyverz.hex [OK] +Checking file size of lets_split_rev2_xyverz.hex [OK] + * File size is fine - 27938/28672 +Detecting USB port, reset your controller now.............. +``` + +En este punto, reinicia la placa y entonces el script detectará el bootloader y procederá a flashear la placa. La información de salida deber ser algo similar a esto: + +``` +Detected controller on USB port at /dev/ttyS15 + +Connecting to programmer: . +Found programmer: Id = "CATERIN"; type = S + Software Version = 1.0; No Hardware Version given. +Programmer supports auto addr increment. +Programmer supports buffered memory access with buffersize=128 bytes. + +Programmer supports the following devices: + Device code: 0x44 + +avrdude.exe: AVR device initialized and ready to accept instructions + +Reading | ################################################## | 100% 0.00s + +avrdude.exe: Device signature = 0x1e9587 (probably m32u4) +avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed + To disable this feature, specify the -D option. +avrdude.exe: erasing chip +avrdude.exe: reading input file "./.build/lets_split_rev2_xyverz.hex" +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: writing flash (27938 bytes): + +Writing | ################################################## | 100% 2.40s + +avrdude.exe: 27938 bytes of flash written +avrdude.exe: verifying flash memory against ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: load data flash data from input file ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex contains 27938 bytes +avrdude.exe: reading on-chip flash data: + +Reading | ################################################## | 100% 0.43s + +avrdude.exe: verifying ... +avrdude.exe: 27938 bytes of flash verified + +avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:FF) + +avrdude.exe done. Thank you. +``` +Si tienes problemas con esto, puede ser necesario que hagas esto: + + sudo make ::avrdude + + +Adicionalmente, si quisieras flashear múltiples placas, usa el siguiente comando: + + make ::avrdude-loop + +Cuando hayas acabado de flashear placas, necesitarás pulsar Ctrl + C o cualquier combinación que esté definida en tu sistema operativo para finalizar el bucle. + + +### HalfKay + +Para dispositivos PJRC (Teensy's), cuando estés listo para compilar y flashear tu firmware, abre tu ventana de terminal y ejecuta el siguiente comando de construcción: + + make ::teensy + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un Ergodox o un Ergodox EZ, usarás este comando: + + make ergodox_ez:xyverz:teensy + +Una vez que el firmware acabe de compilar, deberá mostrar una información de salida como esta: + +``` +Linking: .build/ergodox_ez_xyverz.elf [OK] +Creating load file for flashing: .build/ergodox_ez_xyverz.hex [OK] +Checking file size of ergodox_ez_xyverz.hex [OK] + * File size is fine - 25584/32256 + Teensy Loader, Command Line, Version 2.1 +Read "./.build/ergodox_ez_xyverz.hex": 25584 bytes, 79.3% usage +Waiting for Teensy device... + (hint: press the reset button) + ``` + +En este punto, reinicia tu placa. Una vez que lo hayas hecho, deberás ver una información de salida como esta: + + ``` + Found HalfKay Bootloader +Read "./.build/ergodox_ez_xyverz.hex": 28532 bytes, 88.5% usage +Programming............................................................................................................................................................................ +................................................... +Booting +``` + +### BootloadHID + +Para placas basadas en Bootmapper Client(BMC)/bootloadHID/ATmega32A, cuando estés listo para compilar y flashear tu firmware, abre tu ventana de terminal y ejecuta el comando de construcción: + + make ::bootloaderHID + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un jj40, usarás esté comando: + + make jj40:xyverz:bootloaderHID + +Una vez que el firmware acaba de compilar, mostrará una información de salida como esta: + +``` +Linking: .build/jj40_default.elf [OK] +Creating load file for flashing: .build/jj40_default.hex [OK] +Copying jj40_default.hex to qmk_firmware folder [OK] +Checking file size of jj40_default.hex [OK] + * The firmware size is fine - 21920/28672 (6752 bytes free) +``` + +Después de llegar a este punto, el script de construcción buscará el bootloader DFU cada 5 segundos. Repetirá lo siguiente hasta que se encuentre el dispositivo o hasta que lo canceles. + +``` +Error opening HIDBoot device: The specified device was not found +Trying again in 5s. +``` + +Una vez que lo haga, querrás reinicar el controlador. Debería entonces mostrar una información de salida similar a esta: + +``` +Page size = 128 (0x80) +Device size = 32768 (0x8000); 30720 bytes remaining +Uploading 22016 (0x5600) bytes starting at 0 (0x0) +0x05580 ... 0x05600 +``` + +### STM32 (ARM) + +Para la mayoría de placas ARM (incluyendo la Proton C, Planck Rev 6, y Preonic Rev 3), cuando estés listo para compilar y flashear tu firmware, abre tu ventana de terminal y ejecuta el siguiente comando de construcción: + + make ::dfu-util + +Por ejemplo, si tu keymap se llama "xyverz" y estás construyendo un keymap para un teclado Planck Revision 6, utilizarás este comando y a continuación reiniciarás el teclado con el bootloader (antes de que acabe de compilar): + + make planck/rev6:xyverz:dfu-util + +Una vez que el firmware acaba de compilar, mostrará una información de salida similar a esta: + +``` +Linking: .build/planck_rev6_xyverz.elf [OK] +Creating binary load file for flashing: .build/planck_rev6_xyverz.bin [OK] +Creating load file for flashing: .build/planck_rev6_xyverz.hex [OK] + +Size after: + text data bss dec hex filename + 0 41820 0 41820 a35c .build/planck_rev6_xyverz.hex + +Copying planck_rev6_xyverz.bin to qmk_firmware folder [OK] +dfu-util 0.9 + +Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. +Copyright 2010-2016 Tormod Volden and Stefan Schmidt +This program is Free Software and has ABSOLUTELY NO WARRANTY +Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ + +Invalid DFU suffix signature +A valid DFU suffix will be required in a future dfu-util release!!! +Opening DFU capable USB device... +ID 0483:df11 +Run-time device DFU version 011a +Claiming USB DFU Interface... +Setting Alternate Setting #0 ... +Determining device status: state = dfuERROR, status = 10 +dfuERROR, clearing status +Determining device status: state = dfuIDLE, status = 0 +dfuIDLE, continuing +DFU mode device DFU version 011a +Device returned transfer size 2048 +DfuSe interface name: "Internal Flash " +Downloading to address = 0x08000000, size = 41824 +Download [=========================] 100% 41824 bytes +Download done. +File downloaded successfully +Transitioning to dfuMANIFEST state +``` + +#### STM32 Commands + +Hay un número de comandos DFU que puedes usar para flashear firmware a un dispositivo DFU: + +* `:dfu-util` - El comando por defecto para flashing en dispositivos STM32. +* `:dfu-util-wait` - Esto funciona como el comando por defecto, pero te da (configurable) 10 segundos de tiempo antes de que intente flashear el firmware. Puedes usar `TIME_DELAY=20` desde la líena de comandos para cambiar este tiempo de retardo. + * Eg: `make ::dfu-util TIME_DELAY=5` +* `:dfu-util-split-left` - Flashea el firmware normal, igual que la opción por defecto (`:dfu-util`). Sin embargo, también flashea el fichero EEPROM "Lado Izquierdo" para teclados divididos. +* `:dfu-util-split-right` - Flashea el firmware normal, igual que la opción por defecto (`:dfu-util`). Sin embargo, también flashea el fichero EEPROM "Lado Derecho" para teclados divididos. + +## ¡Pruébalo! + +¡Felicidades! ¡Tu firmware personalizado ha sido programado en tu teclado! + +Pruébalo y asegúrate de que todo funciona de la manera que tu quieres. Hemos escrito [Testeando y depurando](newbs_testing_debugging.md) para redondear esta guía de novatos, así que pásate por allí para aprender cómo resolver problemas con tu funcionalidad personalizada. diff --git a/es/newbs_getting_started.md b/es/newbs_getting_started.md new file mode 100644 index 00000000000..eb0d6d36fbd --- /dev/null +++ b/es/newbs_getting_started.md @@ -0,0 +1,103 @@ +# Introducción + +El teclado de tu computador tiene un procesador dentro de él, no muy distinto del que está dentro de tu ordenador. Este procesador ejecuta software que es responsable de detectar la pulsación de las teclas y enviar informes sobre el estado del teclado cuando las teclas son pulsadas y liberadas. QMK ocupa el rol de ese software. Cuando construyes un keymap personalizado , estas creando el equivalente de un programa ejecutable en tu teclado. + +QMK intenta poner un montón de poder en tus manos haciendo que las cosas fáciles sean fáciles, y las cosas difíciles posibles. No tienes que saber cómo programar para crear keymaps potentes — sólo tienes que seguir un conjunto simple de reglas sintácticas. + +# Comenzando + +Antes de que puedas construir keymaps, necesitarás instalar algun software y configurar tu entorno de construcción. Esto sólo hay que hacerlo una vez sin importar en cuántos teclados planeas configurar el software. + +Si prefieres hacerlo mediante un interfaz gráfico , por favor, considera utilizar el [Configurador QMK](https://config.qmk.fm). En ese caso dirígete a [Construyendo tu primer firmware usando la GUI](newbs_building_firmware_configurator.md). + + +## Descarga el software + +### Editor de texto + +Necesitarás un programa con el que puedas editar y guardar archivos de **texto plano**, en windows puedes utilizar Notepad y en tu Linux puedes utilizar gedit. Estos dos programas son editores simples y funcionales. En macOS ten cuidado con la aplicación de edición de texto por defecto TextEdit: no guardará texto plano a menos de que se le seleccione explícitamente _Make Plain Text_ desde el menú _Format_. + +También puedes descargar e instalar un editor de texto dedicado como [Sublime Text](https://www.sublimetext.com/) o [VS Code](https://code.visualstudio.com/). Esta es probablemente la mejor manera independientemente de la plataforma, ya que estos programas fueron creados específicamente para editar código. + +?> ¿No estás seguro de qué editor de texto utilizar? Laurence Bradford escribió una [estupenda introducción](https://learntocodewith.me/programming/basics/text-editors/) al tema. + +### QMK Toolbox + +QMK Toolbox is an optional graphical program for Windows and macOS that allows you to both program and debug your custom keyboard. You will likely find it invaluable for easily flashing your keyboard and viewing debug messages that it prints. + +[Download the latest release here.](https://github.com/qmk/qmk_toolbox/releases/latest) + +* For Windows: `qmk_toolbox.exe` (portable) or `qmk_toolbox_install.exe` (installer) +* For macOS: `QMK.Toolbox.app.zip` (portable) or `QMK.Toolbox.pkg` (installer) + +## Configura tu entorno + +Hemos intentado hacer QMK lo más fácil de configurar posible. Sólo tienes que preparar tu entorno Linux o Unix, y luego dejar que QMK +instale el resto. + +?> Si no has trabajado con la línea de comandos de Linux/Unix con anterioridad, hay algunos conceptos y comandos básicos que deberías aprender. Estos recursos te enseñarán lo suficiente para poder trabajar con QMK:
+[Comandos de Linux que debería saber](https://www.guru99.com/must-know-linux-commands.html)
+[Algunos comandos básicos de Unix](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +Necesitarás instalar MSYS2 y Git. + +* Sigue las instrucciones de instalación en la [página de MSYS2](http://www.msys2.org). +* Cierra las terminales abiertas de MSYS2 y abre una nueva termial de MSYS2 MinGW 64-bit. +* Instala Git ejecutando este comando: `pacman -S git`. + +### macOS + +Necesitarás instalar Homebrew. Sigue las instrucciones que encontrarás en la [página de Homebrew](https://brew.sh). + +Despueś de que se haya inastalado Homebrew, continúa con _Set Up QMK_. En ese paso ejecutará un script que instalará el resto de paquetes. + +### Linux + +Necesitarás instalar Git. Es bastante probable que ya lo tengas, pero si no, uno de los siguientes comandos debería instalarlo: + +* Debian / Ubuntu / Devuan: `apt-get install git` +* Fedora / Red Hat / CentOS: `yum install git` +* Arch: `pacman -S git` + +?> Docker es también una opción en todas las plataformas. [Haz click aquí si quieres detalles.](getting_started_build_tools.md#docker) + +## Configura QMK + +Una vez que hayas configurado tu entorno Linux/Unix, estarás listo para descargar QMK. Haremos esto utilizando Git para "clonar" el respositorio de QMK. Abre una ventana de Terminal o MSYS2 MinGW y mantenla abierta mientras sigues esta guía. Dentro de esa ventana ejecuta estos dos comandos: + +```shell +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +?> Si ya sabes [cómo usar GitHub](getting_started_github.md), te recomendamos en vez de eso, crees y clones tu propio fork. Si no sabes lo que significa, puedes ignorar este mensaje sin problemas. + +QMK viene con un script para ayudarte a configurar el resto de cosas que necesitarás. Deberías ejecutarlo introduciendo este comando: + + util/qmk_install.sh + +## Prueba tu entorno de construcción + +Ahora que tu entorno de construcción de QMK está configurado, puedes construcir un firmware para tu teclado. Comienza intentado construir el keymap por defecto del teclado. Deberías ser capaz de hacerlo con un comando con este formato: + + make :default + +Por ejemplo, para construir el firmware para un Clueboard 66% deberías usar: + + make clueboard/66/rev3:default + +Cuando esté hecho, deberías tener un montón de información de salida similar a esta: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +# Creando tu keymap + +Ya estás listo para crear tu propio keymap personal! Para hacerlo continua con [Construyendo tu primer firmware](newbs_building_firmware.md). diff --git a/es/newbs_learn_more_resources.md b/es/newbs_learn_more_resources.md new file mode 100644 index 00000000000..34fd7556bf1 --- /dev/null +++ b/es/newbs_learn_more_resources.md @@ -0,0 +1,15 @@ +# Recursos de aprendizaje + +Estos recursos procuran dar miembros nuevos en la communidad QMK un mayor entendimiento de la información proporcionada en la documentación para novatos. + +Recursos de Git: + +* [Excelente tutorial general](https://www.codecademy.com/learn/learn-git) +* [Juego de Git para aprender usando ejemplos](https://learngitbranching.js.org/) +* [Recursos de Git para aprender más sobre GitHub](getting_started_github.md) +* [Recursos de Git dirigidos específicamente a QMK](contributing.md) + + +Recursos para línea de mandatos: + +* [Excelente tutorial general sobre la línea de mandatos](https://www.codecademy.com/learn/learn-the-command-line) diff --git a/es/newbs_testing_debugging.md b/es/newbs_testing_debugging.md new file mode 100644 index 00000000000..ef7412f15c3 --- /dev/null +++ b/es/newbs_testing_debugging.md @@ -0,0 +1,99 @@ +# Testeando y depurando + +Una vez que hayas flasheado tu teclado con un firmware personalizado estarás listo para probarlo. Con un poco de suerte todo funcionará a la primera, pero si no es así, este documento te ayudará a averiguar qué está mal. + +## Probando + +Probar tu teclado es generalmente bastante sencillo. Persiona cada una de las teclas y asegúrate de que envía la tecla correcta. Existen incluso programas que te ayudarán a asegurarte de que no te dejas ninguna tecla sin comprobar. + +Nota: Estos programas no los provée ni están relacionados con QMK. + +* [Switch Hitter](https://elitekeyboards.com/switchhitter.php) (Sólo Windows) +* [Keyboard Viewer](https://www.imore.com/how-use-keyboard-viewer-your-mac) (Sólo Mac) +* [Keyboard Tester](http://www.keyboardtester.com) (Aplicación web) +* [Keyboard Checker](http://keyboardchecker.com) (Aplicación web) + +## Depurando + +Tu teclado mostrará información de depuración si tienes `CONSOLE_ENABLE = yes` en tu `rules.mk`. Por defecto la información de salida es muy limitada, pero puedes encender el modo de depuración para incrementar la información de salida. Utiliza el keycode `DEBUG` de tu keymap, usa la característica [Comando](feature_command.md) para activar el modo depuración, o añade el siguiente código a tu keymap. + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + +### Depurando con QMK Toolbox + +Para plataformas compatibles, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) se puede usar para mostrar mensajes de depuración de tu teclado. + +### Depurando con hid_listen + +¿Prefieres una solución basada en una terminal? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provista por PJRC, se puede usar también para mostrar mensajes de depuración. Hay binarios preconstruídos para Windows,Linux,y MacOS. + + + +## Enviando tus propios mensajes de depuración + +A veces, es útil imprimir mensajes de depuración desde tu [código personalizado](custom_quantum_functions.md). Hacerlo es bastante simple. Comienza incluyendo `print.h` al principio de tu fichero: + + #include + +Después de eso puedes utilzar algunas funciones print diferentes: + +* `print("string")`: Imprime un string simple +* `uprintf("%s string", var)`: Imprime un string formateado +* `dprint("string")` Imprime un string simple, pero sólo cuando el modo de depuración está activo +* `dprintf("%s string", var)`: Imprime un string formateado, pero sólo cuando el modo de depuración está activo + +## Ejemplos de depuración + +Debajo hay una colección de ejemplos de depuración del mundo real. Para información adicional, Dirígete a [Depurando/Encontrando problemas en QMK](faq_debug.md). + +### ¿Que posición en la matriz tiene esta pulsación de tecla? + +Cuando estés portando, o intentando diagnosticar problemas en la pcb, puede ser útil saber si la pulsación de una tecla es escaneada correctamente. Para hablitar la información de registro en este escenario, añade el siguiente código al `keymap.c` de tus keymaps + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // If console is enabled, it will print the matrix position and status of each key pressed +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif + return true; +} +``` + +Ejemplo de salida +```text +Waiting for device:....... +Listening: +KL: kc: 169, col: 0, row: 0, pressed: 1 +KL: kc: 169, col: 0, row: 0, pressed: 0 +KL: kc: 174, col: 1, row: 0, pressed: 1 +KL: kc: 174, col: 1, row: 0, pressed: 0 +KL: kc: 172, col: 2, row: 0, pressed: 1 +KL: kc: 172, col: 2, row: 0, pressed: 0 +``` + +### ¿Cuanto tiempo tardó en escanear la pulsación de una tecla? + +Cuando estés probando problemas en el rendimiento, puede ser útil saber la frecuenta a la cual la matríz de pulsadores se está escaneando. Para hablitar la información de registro en este escenario, añade el siguiente código al `config.h` de tus keymaps + +```c +#define DEBUG_MATRIX_SCAN_RATE +``` + +Ejemplo de salida +```text + > matrix scan frequency: 315 + > matrix scan frequency: 313 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 +``` diff --git a/faq_build.md b/faq_build.md new file mode 100644 index 00000000000..e64c035332a --- /dev/null +++ b/faq_build.md @@ -0,0 +1,69 @@ +# Frequently Asked Build Questions + +This page covers questions about building QMK. If you haven't yet done so, you should read the [Build Environment Setup](getting_started_build_tools.md) and [Make Instructions](getting_started_make_guide.md) guides. + +## Can't Program on Linux +You will need proper permissions to operate a device. For Linux users, see the instructions regarding `udev` rules, below. If you have issues with `udev`, a work-around is to use the `sudo` command. If you are not familiar with this command, check its manual with `man sudo` or [see this webpage](https://linux.die.net/man/8/sudo). + +An example of using `sudo`, when your controller is ATMega32u4: + + $ sudo dfu-programmer atmega32u4 erase --force + $ sudo dfu-programmer atmega32u4 flash your.hex + $ sudo dfu-programmer atmega32u4 reset + +or just: + + $ sudo make ::flash + +Note that running `make` with `sudo` is generally ***not*** a good idea, and you should use one of the former methods, if possible. + +### Linux `udev` Rules + +On Linux, you'll need proper privileges to communicate with the bootloader device. You can either use `sudo` when flashing firmware (not recommended), or place [this file](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) into `/etc/udev/rules.d/`. + +Once added, run the following: + +``` +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +**Note:** With older versions of ModemManager (< 1.12), filtering only works when not in strict mode. The following commands can update that setting: + +``` +printf '[Service]\nExecStart=\nExecStart=/usr/sbin/ModemManager --filter-policy=default' | sudo tee /etc/systemd/system/ModemManager.service.d/policy.conf +sudo systemctl daemon-reload +sudo systemctl restart ModemManager +``` + +### Serial device is not detected in bootloader mode on Linux +Make sure your kernel has appropriate support for your device. If your device uses USB ACM, such as +Pro Micro (Atmega32u4), make sure to include `CONFIG_USB_ACM=y`. Other devices may require `USB_SERIAL` and any of its sub options. + +## Unknown Device for DFU Bootloader + +Issues encountered when flashing keyboards on Windows are most often due to having the wrong drivers installed for the bootloader, or none at all. + +Re-running the QMK installation script (`./util/qmk_install.sh` from the `qmk_firmware` directory in MSYS2 or WSL) or reinstalling the QMK Toolbox may fix the issue. Alternatively, you can download and run the [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) package manually. + +If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig.md) for more detailed information. + +## USB VID and PID +You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product. + +Most boards in QMK use `0xFEED` as the vendor ID. You should look through other keyboards to make sure you pick a unique Product ID. + +Also see this. +https://github.com/tmk/tmk_keyboard/issues/150 + +You can buy a really unique VID:PID here. I don't think you need this for personal use. +- http://www.obdev.at/products/vusb/license.html +- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 + +### I just flashed my keyboard and it does nothing/keypresses don't register - it's also ARM (rev6 planck, clueboard 60, hs60v2, etc...) (Feb 2019) +Due to how EEPROM works on ARM based chips, saved settings may no longer be valid. This affects the default layers, and *may*, under certain circumstances we are still figuring out, make the keyboard unusable. Resetting the EEPROM will correct this. + +[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) can be used to force an eeprom reset. After flashing this image, flash your normal firmware again which should restore your keyboard to _normal_ working order. +[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) + +If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](feature_bootmagic.md) and keyboard info for specifics on how to do this). diff --git a/faq_debug.md b/faq_debug.md new file mode 100644 index 00000000000..7d5473678b3 --- /dev/null +++ b/faq_debug.md @@ -0,0 +1,148 @@ +# Debugging FAQ + +This page details various common questions people have about troubleshooting their keyboards. + +# Debug Console + +## `hid_listen` Can't Recognize Device +When debug console of your device is not ready you will see like this: + +``` +Waiting for device:......... +``` + +once the device is plugged in then *hid_listen* finds it you will get this message: + +``` +Waiting for new device:......................... +Listening: +``` + +If you can't get this 'Listening:' message try building with `CONSOLE_ENABLE=yes` in [Makefile] + +You may need privilege to access the device on OS like Linux. +- try `sudo hid_listen` + +## Can't Get Message on Console +Check: +- *hid_listen* finds your device. See above. +- Enable debug with pressing **Magic**+d. See [Magic Commands](https://github.com/tmk/tmk_keyboard#magic-commands). +- set `debug_enable=true`. See [Testing and Debugging](newbs_testing_debugging.md#debugging) +- try using 'print' function instead of debug print. See **common/print.h**. +- disconnect other devices with console function. See [Issue #97](https://github.com/tmk/tmk_keyboard/issues/97). + +*** + +# Miscellaneous +## Safety Considerations + +You probably don't want to "brick" your keyboard, making it impossible +to rewrite firmware onto it. Here are some of the parameters to show +what things are (and likely aren't) too risky. + +- If your keyboard map does not include RESET, then, to get into DFU + mode, you will need to press the reset button on the PCB, which + requires unscrewing the bottom. +- Messing with tmk_core / common files might make the keyboard + inoperable +- Too large a .hex file is trouble; `make dfu` will erase the block, + test the size (oops, wrong order!), which errors out, failing to + flash the keyboard, leaving it in DFU mode. + - To this end, note that the maximum .hex file size on Planck is + 7000h (28672 decimal) + +``` +Linking: .build/planck_rev4_cbbrowne.elf [OK] +Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] + +Size after: + text data bss dec hex filename + 0 22396 0 22396 577c planck_rev4_cbbrowne.hex +``` + + - The above file is of size 22396/577ch, which is less than + 28672/7000h + - As long as you have a suitable alternative .hex file around, you + can retry, loading that one + - Some of the options you might specify in your keyboard's Makefile + consume extra memory; watch out for BOOTMAGIC_ENABLE, + MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE, API_SYSEX_ENABLE +- DFU tools do /not/ allow you to write into the bootloader (unless + you throw in extra fruit salad of options), so there is little risk + there. +- EEPROM has around a 100000 write cycle. You shouldn't rewrite the + firmware repeatedly and continually; that'll burn the EEPROM + eventually. + +## NKRO Doesn't work +First you have to compile firmware with this build option `NKRO_ENABLE` in **Makefile**. + +Try `Magic` **N** command(`LShift+RShift+N` by default) when **NKRO** still doesn't work. You can use this command to toggle between **NKRO** and **6KRO** mode temporarily. In some situations **NKRO** doesn't work you need to switch to **6KRO** mode, in particular when you are in BIOS. + +If your firmware built with `BOOTMAGIC_ENABLE` you need to turn its switch on by `BootMagic` **N** command(`Space+N` by default). This setting is stored in EEPROM and kept over power cycles. + +https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch + + +## TrackPoint Needs Reset Circuit (PS/2 Mouse Support) +Without reset circuit you will have inconsistent result due to improper initialize of the hardware. See circuit schematic of TPM754. + +- http://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 +- http://www.mikrocontroller.net/attachment/52583/tpm754.pdf + + +## Can't Read Column of Matrix Beyond 16 +Use `1UL<<16` instead of `1<<16` in `read_cols()` in [matrix.h] when your columns goes beyond 16. + +In C `1` means one of [int] type which is [16 bit] in case of AVR so you can't shift left more than 15. You will get unexpected zero when you say `1<<16`. You have to use [unsigned long] type with `1UL`. + +http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 + +## Special Extra Key Doesn't Work (System, Audio Control Keys) +You need to define `EXTRAKEY_ENABLE` in `rules.mk` to use them in QMK. + +``` +EXTRAKEY_ENABLE = yes # Audio control and System control +``` + +## Wakeup from Sleep Doesn't Work + +In Windows check `Allow this device to wake the computer` setting in Power **Management property** tab of **Device Manager**. Also check BIOS setting. + +Pressing any key during sleep should wake host. + +## Using Arduino? + +**Note that Arduino pin naming is different from actual chip.** For example, Arduino pin `D0` is not `PD0`. Check circuit with its schematics yourself. + +- http://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf +- http://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf + +Arduino Leonardo and micro have **ATMega32U4** and can be used for TMK, though Arduino bootloader may be a problem. + +## Enabling JTAG + +By default, the JTAG debugging interface is disabled as soon as the keyboard starts up. JTAG-capable MCUs come from the factory with the `JTAGEN` fuse set, and it takes over certain pins of the MCU that the board may be using for the switch matrix, LEDs, etc. + +If you would like to keep JTAG enabled, just add the following to your `config.h`: + +```c +#define NO_JTAG_DISABLE +``` + +## USB 3 Compatibility +I heard some people have a problem with USB 3 port, try USB 2 port. + + +## Mac Compatibility +### OS X 10.11 and Hub +https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 + + +## Problem on BIOS (UEFI)/Resume (Sleep & Wake)/Power Cycles +Some people reported their keyboard stops working on BIOS and/or after resume(power cycles). + +As of now root of its cause is not clear but some build options seem to be related. In Makefile try to disable those options like `CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE` and/or others. + +https://github.com/tmk/tmk_keyboard/issues/266 +https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/faq_general.md b/faq_general.md new file mode 100644 index 00000000000..8e9771cbcd6 --- /dev/null +++ b/faq_general.md @@ -0,0 +1,53 @@ +# Frequently Asked Questions + +## What is QMK? + +[QMK](https://github.com/qmk), short for Quantum Mechanical Keyboard, is a group of people building tools for custom keyboards. We started with the [QMK firmware](https://github.com/qmk/qmk_firmware), a heavily modified fork of [TMK](https://github.com/tmk/tmk_keyboard). + +## I don't know where to start! + +If this is the case, then you should start with our [Newbs Guide](newbs.md). There is a lot of great info there, and that should cover everything you need to get started. + +If that's an issue, hop onto the [QMK Configurator](https://config.qmk.fm), as that will handle a majority of what you need there. + +## How can I flash the firmware I built? + +First, head to the [Compiling/Flashing FAQ Page](faq_build.md). There is a good deal of info there, and you'll find a bunch of solutions to common issues there. + +## What if I have an issue that isn't covered here? + +Okay, that's fine. Then please check the [open issues in our GitHub](https://github.com/qmk/qmk_firmware/issues) to see if somebody is experiencing the same thing (make sure it's not just similar, but actually the same). + +If you can't find anything, then please open a [new issue](https://github.com/qmk/qmk_firmware/issues/new)! + +## What if I found a bug? + +Then please open an [issue](https://github.com/qmk/qmk_firmware/issues/new), and if you know how to fix it, open up a Pull Request on GitHub with the fix. + +## But `git` and `GitHub` are intimidating! + +Don't worry, we have some pretty nice [Guidelines](newbs_git_best_practices.md) on how to start using `git` and GitHub to make things easier to develop. + +Additionally, you can find additional `git` and GitHub related links [here](newbs_learn_more_resources.md). + +## I have a Keyboard that I want to add support for + +Awesome! Open up a Pull Request for it. We'll review the code, and merge it! + +### What if I want to do brand it with `QMK`? + +That's amazing! We would love to assist you with that! + +In fact, we have a [whole page](https://qmk.fm/powered/) dedicated to adding QMK Branding to your page and keyboard. This covers pretty much everything you need (knowledge and images) to officially support QMK. + +If you have any questions about this, open an issue or head to [Discord](https://discord.gg/Uq7gcHh). + +## What Differences Are There Between QMK and TMK? + +TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK. + +From a technical standpoint QMK builds upon TMK by adding several new features. Most notably QMK has expanded the number of available keycodes and uses these to implement advanced features like `S()`, `LCTL()`, and `MO()`. You can see a complete list of these keycodes in [Keycodes](keycodes.md). + +From a project and community management standpoint TMK maintains all the officially supported keyboards by himself, with a bit of community support. Separate community maintained forks exist or can be created for other keyboards. Only a few keymaps are provided by default, so users typically don't share keymaps with each other. QMK encourages sharing of both keyboards and keymaps through a centrally managed repository, accepting all pull requests that follow the quality standards. These are mostly community maintained, but the QMK team also helps when necessary. + +Both approaches have their merits and their drawbacks, and code flows freely between TMK and QMK when it makes sense. diff --git a/faq_keymap.md b/faq_keymap.md new file mode 100644 index 00000000000..d1d9b919649 --- /dev/null +++ b/faq_keymap.md @@ -0,0 +1,156 @@ +# Keymap FAQ + +This page covers questions people often have about keymaps. If you haven't you should read [Keymap Overview](keymap.md) first. + +## What Keycodes Can I Use? +See [Keycodes](keycodes.md) for an index of keycodes available to you. These link to more extensive documentation when available. + +Keycodes are actually defined in [common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/keycode.h). + +## What Are the Default Keycodes? + +There are 3 standard keyboard layouts in use around the world- ANSI, ISO, and JIS. North America primarily uses ANSI, Europe and Africa primarily use ISO, and Japan uses JIS. Regions not mentioned typically use either ANSI or ISO. The keycodes corresponding to these layouts are shown here: + + +![Keyboard Layout Image](https://i.imgur.com/5wsh5wM.png) + +## How Can I Make Custom Names For Complex Keycodes? + +Sometimes, for readability's sake, it's useful to define custom names for some keycodes. People often define custom names using `#define`. For example: + +```c +#define FN_CAPS LT(_FL, KC_CAPSLOCK) +#define ALT_TAB LALT(KC_TAB) +``` + +This will allow you to use `FN_CAPS` and `ALT_TAB` in your keymap, keeping it more readable. + +## Some Of My Keys Are Swapped Or Not Working + +QMK has two features, Bootmagic and Command, which allow you to change the behavior of your keyboard on the fly. This includes, but is not limited to, swapping Ctrl/Caps, disabling Gui, swapping Alt/Gui, swapping Backspace/Backslash, disabling all keys, and other behavioral modifications. + +As a quick fix try holding down `Space`+`Backspace` while you plug in your keyboard. This will reset the stored settings on your keyboard, returning those keys to normal operation. If that doesn't work look here: + +* [Bootmagic](feature_bootmagic.md) +* [Command](feature_command.md) + +## The Menu Key Isn't Working + +The key found on most modern keyboards that is located between `KC_RGUI` and `KC_RCTL` is actually called `KC_APP`. This is because when that key was invented there was already a key named `MENU` in the relevant standards, so MS chose to call that the `APP` key. + +## `KC_SYSREQ` Isn't Working +Use keycode for Print Screen(`KC_PSCREEN` or `KC_PSCR`) instead of `KC_SYSREQ`. Key combination of 'Alt + Print Screen' is recognized as 'System request'. + +See [issue #168](https://github.com/tmk/tmk_keyboard/issues/168) and +* http://en.wikipedia.org/wiki/Magic_SysRq_key +* http://en.wikipedia.org/wiki/System_request + +## Power Keys Aren't Working + +Somewhat confusingly, there are two "Power" keycodes in QMK: `KC_POWER` in the Keyboard/Keypad HID usage page, and `KC_SYSTEM_POWER` (or `KC_PWR`) in the Consumer page. + +The former is only recognized on macOS, while the latter, `KC_SLEP` and `KC_WAKE` are supported by all three major operating systems, so it is recommended to use those instead. Under Windows, these keys take effect immediately, however on macOS they must be held down until a dialog appears. + +## One Shot Modifier +Solves my personal 'the' problem. I often got 'the' or 'THe' wrongly instead of 'The'. One Shot Shift mitigates this for me. +https://github.com/tmk/tmk_keyboard/issues/67 + +## Modifier/Layer Stuck +Modifier keys or layers can be stuck unless layer switching is configured properly. +For Modifier keys and layer actions you have to place `KC_TRANS` on same position of destination layer to unregister the modifier key or return to previous layer on release event. + +* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching +* http://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 +* https://github.com/tmk/tmk_keyboard/issues/248 + + +## Mechanical Lock Switch Support + +This feature is for *mechanical lock switch* like [this Alps one](http://deskthority.net/wiki/Alps_SKCL_Lock). You can enable it by adding this to your `config.h`: + +``` +#define LOCKING_SUPPORT_ENABLE +#define LOCKING_RESYNC_ENABLE +``` + +After enabling this feature use keycodes `KC_LCAP`, `KC_LNUM` and `KC_LSCR` in your keymap instead. + +Old vintage mechanical keyboards occasionally have lock switches but modern ones don't have. ***You don't need this feature in most case and just use keycodes `KC_CAPS`, `KC_NLCK` and `KC_SLCK`.*** + +## Input Special Characters Other Than ASCII like Cédille 'Ç' + +See the [Unicode](feature_unicode.md) feature. + +## `Fn` Key on macOS + +Unlike most Fn keys, the one on Apple keyboards actually has its own keycode... sort of. It takes the place of the sixth keycode in a basic 6KRO HID report -- so an Apple keyboard is in fact only 5KRO. + +It is technically possible to get QMK to send this key. However, doing so requires modification of the report format to add the state of the Fn key. +Even worse, it is not recognized unless the keyboard's VID and PID match that of a real Apple keyboard. The legal issues that official QMK support for this feature may create mean it is unlikely to happen. + +See [this issue](https://github.com/qmk/qmk_firmware/issues/2179) for detailed information. + +## Keys Supported in Mac OSX? +You can know which keycodes are supported in OSX from this source code. + +`usb_2_adb_keymap` array maps Keyboard/Keypad Page usages to ADB scancodes(OSX internal keycodes). + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c + +And `IOHIDConsumer::dispatchConsumerEvent` handles Consumer page usages. + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp + + +## JIS Keys in Mac OSX +Japanese JIS keyboard specific keys like `無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` are not recognized on OSX. You can use **Seil** to enable those keys, try following options. + +* Enable NFER Key on PC keyboard +* Enable XFER Key on PC keyboard +* Enable KATAKANA Key on PC keyboard + +https://pqrs.org/osx/karabiner/seil.html + + +## RN-42 Bluetooth Doesn't Work with Karabiner +Karabiner - Keymapping tool on Mac OSX - ignores inputs from RN-42 module by default. You have to enable this option to make Karabiner working with your keyboard. +https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 + +See these for the detail of this problem. +https://github.com/tmk/tmk_keyboard/issues/213 +https://github.com/tekezo/Karabiner/issues/403 + + +## Esc and ` on a Single Key + +See the [Grave Escape](feature_grave_esc.md) feature. + +## Eject on Mac OSX +`KC_EJCT` keycode works on OSX. https://github.com/tmk/tmk_keyboard/issues/250 +It seems Windows 10 ignores the code and Linux/Xorg recognizes but has no mapping by default. + +Not sure what keycode Eject is on genuine Apple keyboard actually. HHKB uses `F20` for Eject key(`Fn+f`) on Mac mode but this is not same as Apple Eject keycode probably. + + +## What's `weak_mods` and `real_mods` in `action_util.c` +___TO BE IMPROVED___ + +real_mods is intended to retains state of real/physical modifier key state, while +weak_mods retains state of virtual or temporary modifiers which should not affect state real modifier key. + +Let's say you hold down physical left shift key and type ACTION_MODS_KEY(LSHIFT, KC_A), + +with weak_mods, +* (1) hold down left shift: real_mods |= MOD_BIT(LSHIFT) +* (2) press ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods |= MOD_BIT(LSHIFT) +* (3) release ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods &= ~MOD_BIT(LSHIFT) +real_mods still keeps modifier state. + +without weak mods, +* (1) hold down left shift: real_mods |= MOD_BIT(LSHIFT) +* (2) press ACTION_MODS_KEY(LSHIFT, KC_A): real_mods |= MOD_BIT(LSHIFT) +* (3) release ACTION_MODS_KEY(LSHIFT, KC_A): real_mods &= ~MOD_BIT(LSHIFT) +here real_mods lost state for 'physical left shift'. + +weak_mods is ORed with real_mods when keyboard report is sent. +https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/feature_advanced_keycodes.md b/feature_advanced_keycodes.md new file mode 100644 index 00000000000..745308b29ef --- /dev/null +++ b/feature_advanced_keycodes.md @@ -0,0 +1,44 @@ +# Modifier Keys :id=modifier-keys + +These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent. + +|Key |Aliases |Description | +|----------|-------------------------------|------------------------------------------------------| +|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` | +|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` | +|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` | +|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` | +|`RCTL(kc)`| |Hold Right Control and press `kc` | +|`RSFT(kc)`| |Hold Right Shift and press `kc` | +|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` | +|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` | +|`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)` |Hold Left Shift and GUI and press `kc` | +|`LCA(kc)` | |Hold Left Control and Alt and press `kc` | +|`LSA(kc)` | |Hold Left Shift and Left Alt and press `kc` | +|`RSA(kc)` |`SAGR(kc)` |Hold Right Shift and Right Alt (AltGr) and press `kc` | +|`RCS(kc)` | |Hold Right Control and Right Shift and press `kc` | +|`LCAG(kc)`| |Hold Left Control, Alt and GUI and press `kc` | +|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` | +|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc` | + +You can also chain them, for example `LCTL(LALT(KC_DEL))` or `C(A(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress. + +# Legacy Content :id=legacy-content + +This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for. + +## Layers :id=switching-and-toggling-layers + +* [Layers](feature_layers.md) + +## Mod-Tap :id=mod-tap + +* [Mod-Tap](mod_tap.md) + +## One Shot Keys :id=one-shot-keys + +* [One Shot Keys](one_shot_keys.md) + +## Tap-Hold Configuration Options :id=tap-hold-configuration-options + +* [Tap-Hold Configuration Options](tap_hold.md) diff --git a/feature_audio.md b/feature_audio.md new file mode 100644 index 00000000000..5132dfe9719 --- /dev/null +++ b/feature_audio.md @@ -0,0 +1,323 @@ +# Audio + +Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. + +Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h: + +Timer 1: +`#define B5_AUDIO` +`#define B6_AUDIO` +`#define B7_AUDIO` + +Timer 3: +`#define C4_AUDIO` +`#define C5_AUDIO` +`#define C6_AUDIO` + +If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration: + +``` +STARTUP_SONG // plays when the keyboard starts up (audio.c) +GOODBYE_SONG // plays when you press the RESET key (quantum.c) +AG_NORM_SONG // plays when you press AG_NORM (quantum.c) +AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c) +CG_NORM_SONG // plays when you press CG_NORM (quantum.c) +CG_SWAP_SONG // plays when you press CG_SWAP (quantum.c) +MUSIC_ON_SONG // plays when music mode is activated (process_music.c) +MUSIC_OFF_SONG // plays when music mode is deactivated (process_music.c) +CHROMATIC_SONG // plays when the chromatic music mode is selected (process_music.c) +GUITAR_SONG // plays when the guitar music mode is selected (process_music.c) +VIOLIN_SONG // plays when the violin music mode is selected (process_music.c) +MAJOR_SONG // plays when the major music mode is selected (process_music.c) +``` + +You can override the default songs by doing something like this in your `config.h`: + +```c +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(STARTUP_SOUND) +#endif +``` + +A full list of sounds can be found in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) - feel free to add your own to this list! All available notes can be seen in [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h). + +To play a custom sound at a particular time, you can define a song like this (near the top of the file): + +```c +float my_song[][2] = SONG(QWERTY_SOUND); +``` + +And then play your song like this: + +```c +PLAY_SONG(my_song); +``` + +Alternatively, you can play it in a loop like this: + +```c +PLAY_LOOP(my_song); +``` + +It's advised that you wrap all audio features in `#ifdef AUDIO_ENABLE` / `#endif` to avoid causing problems when audio isn't built into the keyboard. + +The available keycodes for audio are: + +* `AU_ON` - Turn Audio Feature on +* `AU_OFF` - Turn Audio Feature off +* `AU_TOG` - Toggle Audio Feature state + +!> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. + +## ARM Audio Volume + +For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `DAC_SAMPLE_MAX` in your `config.h`: + +```c +#define DAC_SAMPLE_MAX 65535U +``` + +## Music Mode + +The music mode maps your columns to a chromatic scale, and your rows to octaves. This works best with ortholinear keyboards, but can be made to work with others. All keycodes less than `0xFF` get blocked, so you won't type while playing notes - if you have special keys/mods, those will still work. A work-around for this is to jump to a different layer with KC_NOs before (or after) enabling music mode. + +Recording is experimental due to some memory issues - if you experience some weird behavior, unplugging/replugging your keyboard will fix things. + +Keycodes available: + +* `MU_ON` - Turn music mode on +* `MU_OFF` - Turn music mode off +* `MU_TOG` - Toggle music mode +* `MU_MOD` - Cycle through the music modes: + * `CHROMATIC_MODE` - Chromatic scale, row changes the octave + * `GUITAR_MODE` - Chromatic scale, but the row changes the string (+5 st) + * `VIOLIN_MODE` - Chromatic scale, but the row changes the string (+7 st) + * `MAJOR_MODE` - Major scale + +In music mode, the following keycodes work differently, and don't pass through: + +* `LCTL` - start a recording +* `LALT` - stop recording/stop playing +* `LGUI` - play recording +* `KC_UP` - speed-up playback +* `KC_DOWN` - slow-down playback + +The pitch standard (`PITCH_STANDARD_A`) is 440.0f by default - to change this, add something like this to your `config.h`: + + #define PITCH_STANDARD_A 432.0f + +You can completely disable Music Mode as well. This is useful, if you're pressed for space on your controller. To disable it, add this to your `config.h`: + + #define NO_MUSIC_MODE + +### Music Mask + +By default, `MUSIC_MASK` is set to `keycode < 0xFF` which means keycodes less than `0xFF` are turned into notes, and don't output anything. You can change this by defining this in your `config.h` like this: + + #define MUSIC_MASK keycode != KC_NO + +Which will capture all keycodes - be careful, this will get you stuck in music mode until you restart your keyboard! + +For a more advanced way to control which keycodes should still be processed, you can use `music_mask_kb(keycode)` in `.c` and `music_mask_user(keycode)` in your `keymap.c`: + + bool music_mask_user(uint16_t keycode) { + switch (keycode) { + case RAISE: + case LOWER: + return false; + default: + return true; + } + } + +Things that return false are not part of the mask, and are always processed. + +### Music Map + +By default, the Music Mode uses the columns and row to determine the scale for the keys. For a board that uses a rectangular matrix that matches the keyboard layout, this is just fine. However, for boards that use a more complicated matrix (such as the Planck Rev6, or many split keyboards) this would result in a very skewed experience. + +However, the Music Map option allows you to remap the scaling for the music mode, so it fits the layout, and is more natural. + +To enable this feature, add `#define MUSIC_MAP` to your `config.h` file, and then you will want to add a `uint8_t music_map` to your keyboard's `c` file, or your `keymap.c`. + +```c +const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x12( + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +); +``` + +You will want to use whichever `LAYOUT` macro that your keyboard uses here. This maps it to the correct key location. Start in the bottom left of the keyboard layout, and move to the right, and then upwards. Fill in all the entries until you have a complete matrix. + +You can look at the [Planck Keyboard](https://github.com/qmk/qmk_firmware/blob/e9ace1487887c1f8b4a7e8e6d87c322988bec9ce/keyboards/planck/planck.c#L24-L29) as an example of how to implement this. + +## Audio Click + +This adds a click sound each time you hit a button, to simulate click sounds from the keyboard. And the sounds are slightly different for each keypress, so it doesn't sound like a single long note, if you type rapidly. + +* `CK_TOGG` - Toggles the status (will play sound if enabled) +* `CK_ON` - Turns on Audio Click (plays sound) +* `CK_OFF` - Turns off Audio Click (doesn't play sound) +* `CK_RST` - Resets the frequency to the default state (plays sound at default frequency) +* `CK_UP` - Increases the frequency of the clicks (plays sound at new frequency) +* `CK_DOWN` - Decreases the frequency of the clicks (plays sound at new frequency) + + +The feature is disabled by default, to save space. To enable it, add this to your `config.h`: + + #define AUDIO_CLICKY + + +You can configure the default, min and max frequencies, the stepping and built in randomness by defining these values: + +| Option | Default Value | Description | +|--------|---------------|-------------| +| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | Sets the default/starting audio frequency for the clicky sounds. | +| `AUDIO_CLICKY_FREQ_MIN` | 65.0f | Sets the lowest frequency (under 60f are a bit buggy). | +| `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | Sets the the highest frequency. Too high may result in coworkers attacking you. | +| `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f| Sets the stepping of UP/DOWN key codes. This is a multiplicative factor. The default steps the frequency up/down by a musical minor third. | +| `AUDIO_CLICKY_FREQ_RANDOMNESS` | 0.05f | Sets a factor of randomness for the clicks, Setting this to `0f` will make each click identical, and `1.0f` will make this sound much like the 90's computer screen scrolling/typing effect. | +| `AUDIO_CLICKY_DELAY_DURATION` | 1 | An integer note duration where 1 is 1/16th of the tempo, or a sixty-fourth note (see `quantum/audio/musical_notes.h` for implementation details). The main clicky effect will be delayed by this duration. Adjusting this to values around 6-12 will help compensate for loud switches. | + + + + +## MIDI Functionality + +This is still a WIP, but check out `quantum/process_keycode/process_midi.c` to see what's happening. Enable from the Makefile. + + +## Audio Keycodes + +|Key |Aliases |Description | +|----------------|---------|----------------------------------| +|`AU_ON` | |Audio mode on | +|`AU_OFF` | |Audio mode off | +|`AU_TOG` | |Toggles Audio mode | +|`CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode | +|`CLICKY_UP` |`CK_UP` |Increases frequency of the clicks | +|`CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks | +|`CLICKY_RESET` |`CK_RST` |Resets frequency to default | +|`MU_ON` | |Turns on Music Mode | +|`MU_OFF` | |Turns off Music Mode | +|`MU_TOG` | |Toggles Music Mode | +|`MU_MOD` | |Cycles through the music modes | + + diff --git a/feature_auto_shift.md b/feature_auto_shift.md new file mode 100644 index 00000000000..b21a7690d9e --- /dev/null +++ b/feature_auto_shift.md @@ -0,0 +1,167 @@ +# Auto Shift: Why Do We Need a Shift Key? + +Tap a key and you get its character. Tap a key, but hold it *slightly* longer +and you get its shifted state. Voilà! No shift key needed! + +## Why Auto Shift? + +Many people suffer from various forms of RSI. A common cause is stretching your +fingers repetitively long distances. For us on the keyboard, the pinky does that +all too often when reaching for the shift key. Auto Shift looks to alleviate that +problem. + +## How Does It Work? + +When you tap a key, it stays depressed for a short period of time before it is +then released. This depressed time is a different length for everyone. Auto Shift +defines a constant `AUTO_SHIFT_TIMEOUT` which is typically set to twice your +normal pressed state time. When you press a key, a timer starts and then stops +when you release the key. If the time depressed is greater than or equal to the +`AUTO_SHIFT_TIMEOUT`, then a shifted version of the key is emitted. If the time +is less than the `AUTO_SHIFT_TIMEOUT` time, then the normal state is emitted. + +## Are There Limitations to Auto Shift? + +Yes, unfortunately. + +1. Key repeat will cease to work. For example, before if you wanted 20 'a' + characters, you could press and hold the 'a' key for a second or two. This no + longer works with Auto Shift because it is timing your depressed time instead + of emitting a depressed key state to your operating system. +2. You will have characters that are shifted when you did not intend on shifting, and + other characters you wanted shifted, but were not. This simply comes down to + practice. As we get in a hurry, we think we have hit the key long enough + for a shifted version, but we did not. On the other hand, we may think we are + tapping the keys, but really we have held it for a little longer than + anticipated. + +## How Do I Enable Auto Shift? + +Add to your `rules.mk` in the keymap folder: + + AUTO_SHIFT_ENABLE = yes + +If no `rules.mk` exists, you can create one. + +Then compile and install your new firmware with Auto Key enabled! That's it! + +## Modifiers + +By default, Auto Shift is disabled for any key press that is accompanied by one or more +modifiers. Thus, Ctrl+A that you hold for a really long time is not the same +as Ctrl+Shift+A. + +You can re-enable Auto Shift for modifiers by adding a define to your `config.h` + +```c +#define AUTO_SHIFT_MODIFIERS +``` + +In which case, Ctrl+A held past the `AUTO_SHIFT_TIMEOUT` will be sent as Ctrl+Shift+A + + +## Configuring Auto Shift + +If desired, there is some configuration that can be done to change the +behavior of Auto Shift. This is done by setting various variables the +`config.h` file located in your keymap folder. If no `config.h` file exists, you can create one. + +A sample is + +```c +#pragma once + +#define AUTO_SHIFT_TIMEOUT 150 +#define NO_AUTO_SHIFT_SPECIAL +``` + +### AUTO_SHIFT_TIMEOUT (Value in ms) + +This controls how long you have to hold a key before you get the shifted state. +Obviously, this is different for everyone. For the common person, a setting of +135 to 150 works great. However, one should start with a value of at least 175, which +is the default value. Then work down from there. The idea is to have the shortest time required to get the shifted state without having false positives. + +Play with this value until things are perfect. Many find that all will work well +at a given value, but one or two keys will still emit the shifted state on +occasion. This is simply due to habit and holding some keys a little longer +than others. Once you find this value, work on tapping your problem keys a little +quicker than normal and you will be set. + +?> Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details! + +### NO_AUTO_SHIFT_SPECIAL (simple define) + +Do not Auto Shift special keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>, +and /? + +### NO_AUTO_SHIFT_NUMERIC (simple define) + +Do not Auto Shift numeric keys, zero through nine. + +### NO_AUTO_SHIFT_ALPHA (simple define) + +Do not Auto Shift alpha characters, which include A through Z. + +## Using Auto Shift Setup + +This will enable you to define three keys temporarily to increase, decrease and report your `AUTO_SHIFT_TIMEOUT`. + +### Setup + +Map three keys temporarily in your keymap: + +| Key Name | Description | +|----------|-----------------------------------------------------| +| KC_ASDN | Lower the Auto Shift timeout variable (down) | +| KC_ASUP | Raise the Auto Shift timeout variable (up) | +| KC_ASRP | Report your current Auto Shift timeout value | +| KC_ASON | Turns on the Auto Shift Function | +| KC_ASOFF | Turns off the Auto Shift Function | +| KC_ASTG | Toggles the state of the Auto Shift feature | + +Compile and upload your new firmware. + +### Use + +It is important to note that during these tests, you should be typing +completely normal and with no intention of shifted keys. + +1. Type multiple sentences of alphabetical letters. +2. Observe any upper case letters. +3. If there are none, press the key you have mapped to `KC_ASDN` to decrease + time Auto Shift timeout value and go back to step 1. +4. If there are some upper case letters, decide if you need to work on tapping + those keys with less down time, or if you need to increase the timeout. +5. If you decide to increase the timeout, press the key you have mapped to + `KC_ASUP` and go back to step 1. +6. Once you are happy with your results, press the key you have mapped to + `KC_ASRP`. The keyboard will type by itself the value of your + `AUTO_SHIFT_TIMEOUT`. +7. Update `AUTO_SHIFT_TIMEOUT` in your `config.h` with the value reported. +8. Add `AUTO_SHIFT_NO_SETUP` to your `config.h`. +9. Remove the key bindings `KC_ASDN`, `KC_ASUP` and `KC_ASRP`. +10. Compile and upload your new firmware. + +#### An Example Run + + hello world. my name is john doe. i am a computer programmer playing with + keyboards right now. + + [PRESS KC_ASDN quite a few times] + + heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH + KEYboArDS RiGHT NOw. + + [PRESS KC_ASUP a few times] + + hello world. my name is john Doe. i am a computer programmer playing with + keyboarDs right now. + + [PRESS KC_ASRP] + + 115 + +The keyboard typed `115` which represents your current `AUTO_SHIFT_TIMEOUT` +value. You are now set! Practice on the *D* key a little bit that showed up +in the testing and you'll be golden. diff --git a/feature_backlight.md b/feature_backlight.md new file mode 100644 index 00000000000..6bb2bbed844 --- /dev/null +++ b/feature_backlight.md @@ -0,0 +1,217 @@ +# Backlighting :id=backlighting + +Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard. + +QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming. + +The MCU can only supply so much current to its GPIO pins. Instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs. + +Most keyboards have backlighting enabled by default if they support it, but if it is not working for you, check that your `rules.mk` includes the following: + +```makefile +BACKLIGHT_ENABLE = yes +``` + +## Keycodes :id=keycodes + +Once enabled, the following keycodes below can be used to change the backlight level. + +|Key |Description | +|---------|-----------------------------------| +|`BL_TOGG`|Turn the backlight on or off | +|`BL_STEP`|Cycle through backlight levels | +|`BL_ON` |Set the backlight to max brightness| +|`BL_OFF` |Turn the backlight off | +|`BL_INC` |Increase the backlight level | +|`BL_DEC` |Decrease the backlight level | +|`BL_BRTG`|Toggle backlight breathing | + +## Functions :id=functions + +These functions can be used to change the backlighting in custom code: + +|Function |Description | +|------------------------|--------------------------------------------| +|`backlight_toggle()` |Turn the backlight on or off | +|`backlight_enable()` |Turn the backlight on | +|`backlight_disable()` |Turn the backlight off | +|`backlight_step()` |Cycle through backlight levels | +|`backlight_increase()` |Increase the backlight level | +|`backlight_decrease()` |Decrease the backlight level | +|`backlight_level(x)` |Sets the backlight level to specified level | +|`get_backlight_level()` |Return the current backlight level | +|`is_backlight_enabled()`|Return whether the backlight is currently on| + +If backlight breathing is enabled (see below), the following functions are also available: + +|Function |Description | +|---------------------|--------------------------------------| +|`breathing_toggle()` |Turn the backlight breathing on or off| +|`breathing_enable()` |Turns on backlight breathing | +|`breathing_disable()`|Turns off backlight breathing | + +## Configuration :id=configuration + +To select which driver to use, configure your `rules.mk` with the following: + +```makefile +BACKLIGHT_DRIVER = software +``` + +Valid driver values are `pwm`, `software`, `custom` or `no`. See below for help on individual drivers. + +To configure the backlighting, `#define` these in your `config.h`: + +|Define |Default |Description | +|---------------------|-------------|-------------------------------------------------------------------------------------| +|`BACKLIGHT_PIN` |*Not defined*|The pin that controls the LED(s) | +|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) | +|`BACKLIGHT_CAPS_LOCK`|*Not defined*|Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) | +|`BACKLIGHT_BREATHING`|*Not defined*|Enable backlight breathing, if supported | +|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds | +|`BACKLIGHT_ON_STATE` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low| + +Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`. + +### Backlight On State :id=backlight-on-state + +Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*. +Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead. + +This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define. + +### AVR Driver :id=avr-driver + +The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be: + +```makefile +BACKLIGHT_DRIVER = pwm +``` + +#### Caveats :id=avr-caveats + +On AVR boards, QMK automatically decides which driver to use according to the following table: + +|Backlight Pin|AT90USB64/128|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P| +|-------------|-------------|-------------|-------------|---------|-----------| +|`B1` | | | | |Timer 1 | +|`B2` | | | | |Timer 1 | +|`B5` |Timer 1 |Timer 1 | | | | +|`B6` |Timer 1 |Timer 1 | | | | +|`B7` |Timer 1 |Timer 1 |Timer 1 | | | +|`C4` |Timer 3 | | | | | +|`C5` |Timer 3 | |Timer 1 | | | +|`C6` |Timer 3 |Timer 3 |Timer 1 | | | +|`D4` | | | |Timer 1 | | +|`D5` | | | |Timer 1 | | + +All other pins will use timer-assisted software PWM: + +|Audio Pin|Audio Timer|Software PWM Timer| +|---------|-----------|------------------| +|`C4` |Timer 3 |Timer 1 | +|`C5` |Timer 3 |Timer 1 | +|`C6` |Timer 3 |Timer 1 | +|`B5` |Timer 1 |Timer 3 | +|`B6` |Timer 1 |Timer 3 | +|`B7` |Timer 1 |Timer 3 | + +When both timers are in use for Audio, the backlight PWM cannot use a hardware timer, and will instead be triggered during the matrix scan. In this case, breathing is not supported, and the backlight might flicker, because the PWM computation may not be called with enough timing precision. + +#### Hardware PWM Implementation :id=hardware-pwm-implementation + +When using the supported pins for backlighting, QMK will use a hardware timer configured to output a PWM signal. This timer will count up to `ICRx` (by default `0xFFFF`) before resetting to 0. +The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the backlight pin will go low, and is pulled high again when the counter resets. +In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on. + +The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second. +In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM. + +#### Timer Assisted PWM Implementation :id=timer-assisted-implementation + +When `BACKLIGHT_PIN` is not set to a hardware backlight pin, QMK will use a hardware timer configured to trigger software interrupts. This time will count up to `ICRx` (by default `0xFFFF`) before resetting to 0. +When resetting to 0, the CPU will fire an OVF (overflow) interrupt that will turn the LEDs on, starting the duty cycle. +The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the CPU will fire a Compare Output match interrupt, which will turn the LEDs off. +In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on. + +The breathing effect is the same as in the hardware PWM implementation. + +### ARM Driver :id=arm-configuration + +While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be: + +```makefile +BACKLIGHT_DRIVER = pwm +``` + +#### ChibiOS Configuration :id=arm-configuration + +The following `#define`s apply only to ARM-based keyboards: + +|Define |Default|Description | +|-----------------------|-------|-----------------------------------| +|`BACKLIGHT_PWM_DRIVER` |`PWMD4`|The PWM driver to use | +|`BACKLIGHT_PWM_CHANNEL`|`3` |The PWM channel to use | +|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use| + +See the ST datasheet for your particular MCU to determine these values. Unless you are designing your own keyboard, you generally should not need to change them. + +#### Caveats :id=arm-caveats + +Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration. + +### Software PWM Driver :id=software-pwm-driver + +In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your `rules.mk`: + +```makefile +BACKLIGHT_DRIVER = software +``` + +#### Multiple Backlight Pins :id=multiple-backlight-pins + +Most keyboards have only one backlight pin which control all backlight LEDs (especially if the backlight is connected to an hardware PWM pin). +In software PWM, it is possible to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle. + +This feature allows to set, for instance, the Caps Lock LED's (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped Control in place of Caps Lock and you need the Caps Lock LED to be part of the backlight instead of being activated when Caps Lock is on, as it is usually wired to a separate pin from the backlight. + +To activate multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`: + +```c +#define BACKLIGHT_PINS { F5, B2 } +``` + +### Custom Driver :id=custom-driver + +If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using this simple API provided by QMK. To enable, add this to your `rules.mk`: + +```makefile +BACKLIGHT_DRIVER = custom +``` + +Then implement any of these hooks: + +```c +void backlight_init_ports(void) { + // Optional - runs on startup + // Usually you want to configure pins here +} +void backlight_set(uint8_t level) { + // Optional - runs on level change + // Usually you want to respond to the new value +} + +void backlight_task(void) { + // Optional - runs periodically + // Note that this is called in the main keyboard loop, + // so long running actions here can cause performance issues +} +``` + +## Example Schematic + +In this typical example, the backlight LEDs are all connected in parallel towards an N-channel MOSFET. Its gate pin is wired to one of the microcontroller's GPIO pins through a 470Ω resistor to avoid ringing. +A pulldown resistor is also placed between the gate pin and ground to keep it at a defined state when it is not otherwise being driven by the MCU. +The values of these resistors are not critical - see [this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) for more information. + +![Backlight example circuit](https://i.imgur.com/BmAvoUC.png) diff --git a/feature_bluetooth.md b/feature_bluetooth.md new file mode 100644 index 00000000000..08e5f24ac55 --- /dev/null +++ b/feature_bluetooth.md @@ -0,0 +1,45 @@ +# Bluetooth + +## Bluetooth Known Supported Hardware + +Currently Bluetooth support is limited to AVR based chips. For Bluetooth 2.1, QMK has support for RN-42 modules. For more recent BLE protocols, currently only the Adafruit Bluefruit SPI Friend is directly supported. BLE is needed to connect to iOS devices. Note iOS does not support mouse input. + +|Board |Bluetooth Protocol |Connection Type |rules.mk |Bluetooth Chip| +|----------------------------------------------------------------|----------------------------|----------------|---------------------------|--------------| +|Roving Networks RN-42 (Sparkfun Bluesmirf) |Bluetooth Classic | UART |`BLUETOOTH = RN42` | RN-42 | +|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy | SPI |`BLUETOOTH = AdafruitBLE` | nRF51822 | + +Not Supported Yet but possible: +* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514) +* HC-05 boards flashed with RN-42 firmware. They apparently both use the CSR BC417 Chip. Flashing it with RN-42 firmware gives it HID capability. +* Sparkfun Bluetooth Mate +* HM-13 based boards + +### Adafruit BLE SPI Friend +Currently The only bluetooth chipset supported by QMK is the Adafruit Bluefruit SPI Friend. It's a Nordic nRF5182 based chip running Adafruit's custom firmware. Data is transmitted via Adafruit's SDEP over Hardware SPI. The [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) is supported as it's an AVR mcu connected via SPI to the Nordic BLE chip with Adafruit firmware. If Building a custom board with the SPI friend it would be easiest to just use the pin selection that the 32u4 feather uses but you can change the pins in the config.h options with the following defines: +* #define AdafruitBleResetPin D4 +* #define AdafruitBleCSPin B4 +* #define AdafruitBleIRQPin E6 + +A Bluefruit UART friend can be converted to an SPI friend, however this [requires](https://github.com/qmk/qmk_firmware/issues/2274) some reflashing and soldering directly to the MDBT40 chip. + + + +## Bluetooth Rules.mk Options + +The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`. + +Use only one of these to enable Bluetooth: +* BLUETOOTH_ENABLE = yes (Legacy Option) +* BLUETOOTH = RN42 +* BLUETOOTH = AdafruitBLE + +## Bluetooth Keycodes + +This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both. + +|Name |Description | +|----------|----------------------------------------------| +|`OUT_AUTO`|Automatically switch between USB and Bluetooth| +|`OUT_USB` |USB only | +|`OUT_BT` |Bluetooth only | diff --git a/feature_bootmagic.md b/feature_bootmagic.md new file mode 100644 index 00000000000..f084052cc74 --- /dev/null +++ b/feature_bootmagic.md @@ -0,0 +1,177 @@ +# Bootmagic + +There are three separate but related features that allow you to change the behavior of your keyboard without reflashing. While each of them have similar functionality, it is accessed in different ways depending on how your keyboard is configured. + +**Bootmagic** is a system for configuring your keyboard while it initializes. To trigger a Bootmagic command, hold down the Bootmagic key and one or more command keys. + +**Bootmagic Keycodes** are prefixed with `MAGIC_`, and allow you to access the Bootmagic functionality *after* your keyboard has initialized. To use the keycodes, assign them to your keymap as you would any other keycode. + +**Command**, formerly known as **Magic**, is another feature that allows you to control different aspects of your keyboard. While it shares some functionality with Bootmagic, it also allows you to do things that Bootmagic does not, such as printing version information to the console. For more information, see [Command](feature_command.md). + +On some keyboards Bootmagic is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk` with: + +```make +BOOTMAGIC_ENABLE = full +``` + +?> You may see `yes` being used in place of `full`, and this is okay. However, `yes` is deprecated, and ideally `full` (or `lite`) should be used instead. + +Additionally, you can use [Bootmagic Lite](#bootmagic-lite) (a scaled down, very basic version of Bootmagic) by adding the following to your `rules.mk` file: + +```make +BOOTMAGIC_ENABLE = lite +``` + +## Hotkeys + +Hold down the Bootmagic key (Space by default) and the desired hotkey while plugging in your keyboard. For example, holding Space+`B` should cause it to enter the bootloader. + +|Hotkey |Description | +|------------------|---------------------------------------------| +|Escape |Ignore Bootmagic configuration in EEPROM | +|`B` |Enter the bootloader | +|`D` |Toggle debugging over serial | +|`X` |Toggle key matrix debugging | +|`K` |Toggle keyboard debugging | +|`M` |Toggle mouse debugging | +|`L` |Set "Left Hand" for EE_HANDS handedness | +|`R` |Set "Right Hand" for EE_HANDS handedness | +|Backspace |Clear the EEPROM | +|Caps Lock |Toggle treating Caps Lock as Left Control | +|Left Control |Toggle swapping Caps Lock and Left Control | +|Left Alt |Toggle swapping Left Alt and Left GUI | +|Right Alt |Toggle swapping Right Alt and Right GUI | +|Left GUI |Toggle the GUI keys (useful when gaming) | +|`|Toggle swapping ` and Escape| +|`\` |Toggle swapping `\` and Backspace | +|`N` |Toggle N-Key Rollover (NKRO) | +|`0` |Make layer 0 the default layer | +|`1` |Make layer 1 the default layer | +|`2` |Make layer 2 the default layer | +|`3` |Make layer 3 the default layer | +|`4` |Make layer 4 the default layer | +|`5` |Make layer 5 the default layer | +|`6` |Make layer 6 the default layer | +|`7` |Make layer 7 the default layer | + +## Keycodes :id=keycodes + +|Key |Aliases |Description | +|----------------------------------|---------|--------------------------------------------------------------------------| +|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control | +|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control | +|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control | +|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control | +|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI | +|`MAGIC_UNSWAP_LCTL_LGUI` |`LCG_NRM`|Unswap Left Control and GUI | +|`MAGIC_SWAP_RCTL_RGUI` |`RCG_SWP`|Swap Right Control and GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` |`RCG_NRM`|Unswap Right Control and GUI | +|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Control and GUI on both sides | +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Control and GUI on both sides | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Control and GUI swap on both sides | +|`MAGIC_SWAP_LALT_LGUI` |`LAG_SWP`|Swap Left Alt and GUI | +|`MAGIC_UNSWAP_LALT_LGUI` |`LAG_NRM`|Unswap Left Alt and GUI | +|`MAGIC_SWAP_RALT_RGUI` |`RAG_SWP`|Swap Right Alt and GUI | +|`MAGIC_UNSWAP_RALT_RGUI` |`RAG_NRM`|Unswap Right Alt and GUI | +|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | +|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | +|`MAGIC_NO_GUI` |`GUI_OFF`|Disable the GUI keys | +|`MAGIC_UNNO_GUI` |`GUI_ON` |Enable the GUI keys | +|`MAGIC_SWAP_GRAVE_ESC` |`GE_SWAP`|Swap ` and Escape | +|`MAGIC_UNSWAP_GRAVE_ESC` |`GE_NORM`|Unswap ` and Escape | +|`MAGIC_SWAP_BACKSLASH_BACKSPACE` |`BS_SWAP`|Swap `\` and Backspace | +|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|`BS_NORM`|Unswap `\` and Backspace | +|`MAGIC_HOST_NKRO` |`NK_ON` |Enable N-key rollover | +|`MAGIC_UNHOST_NKRO` |`NK_OFF` |Disable N-key rollover | +|`MAGIC_TOGGLE_NKRO` |`NK_TOGG`|Toggle N-key rollover | +|`MAGIC_EE_HANDS_LEFT` |`EH_LEFT`|Set the master half of a split keyboard as the left hand (for `EE_HANDS`) | +|`MAGIC_EE_HANDS_RIGHT` |`EH_RGHT`|Set the master half of a split keyboard as the right hand (for `EE_HANDS`)| + +## Configuration + +If you would like to change the hotkey assignments for Bootmagic, `#define` these in your `config.h` at either the keyboard or keymap level. + +|Define |Default |Description | +|----------------------------------------|-------------|---------------------------------------------------| +|`BOOTMAGIC_KEY_SALT` |`KC_SPACE` |The Bootmagic key | +|`BOOTMAGIC_KEY_SKIP` |`KC_ESC` |Ignore Bootmagic configuration in EEPROM | +|`BOOTMAGIC_KEY_EEPROM_CLEAR` |`KC_BSPACE` |Clear the EEPROM configuration | +|`BOOTMAGIC_KEY_BOOTLOADER` |`KC_B` |Enter the bootloader | +|`BOOTMAGIC_KEY_DEBUG_ENABLE` |`KC_D` |Toggle debugging over serial | +|`BOOTMAGIC_KEY_DEBUG_MATRIX` |`KC_X` |Toggle matrix debugging | +|`BOOTMAGIC_KEY_DEBUG_KEYBOARD` |`KC_K` |Toggle keyboard debugging | +|`BOOTMAGIC_KEY_DEBUG_MOUSE` |`KC_M` |Toggle mouse debugging | +|`BOOTMAGIC_KEY_EE_HANDS_LEFT` |`KC_L` |Set "Left Hand" for EE_HANDS handedness | +|`BOOTMAGIC_KEY_EE_HANDS_RIGHT` |`KC_R` |Set "Right Hand" for EE_HANDS handedness | +|`BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK` |`KC_LCTRL` |Swap Left Control and Caps Lock | +|`BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL` |`KC_CAPSLOCK`|Toggle treating Caps Lock as Left Control | +|`BOOTMAGIC_KEY_SWAP_LALT_LGUI` |`KC_LALT` |Toggle swapping Left Alt and Left GUI (for macOS) | +|`BOOTMAGIC_KEY_SWAP_RALT_RGUI` |`KC_RALT` |Toggle swapping Right Alt and Right GUI (for macOS)| +|`BOOTMAGIC_KEY_NO_GUI` |`KC_LGUI` |Toggle the GUI keys (useful when gaming) | +|`BOOTMAGIC_KEY_SWAP_GRAVE_ESC` |`KC_GRAVE` |Toggle swapping ` and Escape | +|`BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE`|`KC_BSLASH` |Toggle swapping `\` and Backspace | +|`BOOTMAGIC_HOST_NKRO` |`KC_N` |Toggle N-Key Rollover (NKRO) | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_0` |`KC_0` |Make layer 0 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_1` |`KC_1` |Make layer 1 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_2` |`KC_2` |Make layer 2 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_3` |`KC_3` |Make layer 3 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_4` |`KC_4` |Make layer 4 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_5` |`KC_5` |Make layer 5 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_6` |`KC_6` |Make layer 6 the default layer | +|`BOOTMAGIC_KEY_DEFAULT_LAYER_7` |`KC_7` |Make layer 7 the default layer | + +# Bootmagic Lite :id=bootmagic-lite + +In addition to the full blown Bootmagic feature, is the Bootmagic Lite feature that only handles jumping into the bootloader. This is great for boards that don't have a physical reset button but you need a way to jump into the bootloader, and don't want to deal with the headache that Bootmagic can cause. + +To enable this version of Bootmagic, you need to enable it in your `rules.mk` with: + +```make +BOOTMAGIC_ENABLE = lite +``` + +Additionally, you may want to specify which key to use. This is especially useful for keyboards that have unusual matrices. To do so, you need to specify the row and column of the key that you want to use. Add these entries to your `config.h` file: + +```c +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 1 +``` + +By default, these are set to 0 and 0, which is usually the "ESC" key on a majority of keyboards. + +And to trigger the bootloader, you hold this key down when plugging the keyboard in. Just the single key. + +!> Using bootmagic lite will **always reset** the EEPROM, so you will lose any settings that have been saved. + +## Split Keyboards + +When handedness is predetermined via an option like `SPLIT_HAND_PIN`, you might need to configure a different key between halves. This To do so, add these entries to your `config.h` file: + +```c +#define BOOTMAGIC_LITE_ROW_RIGHT 4 +#define BOOTMAGIC_LITE_COLUMN_RIGHT 1 +``` + +By default, these values are not set. + +## Advanced Bootmagic Lite + +The `bootmagic_lite` function is defined weakly, so that you can replace this in your code, if you need. A great example of this is the Zeal60 boards that have some additional handling needed. + +To replace the function, all you need to do is add something like this to your code: + +```c +void bootmagic_lite(void) { + matrix_scan(); + wait_ms(DEBOUNCE * 2); + matrix_scan(); + + if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { + // Jump to bootloader. + bootloader_jump(); + } +} +``` + +You can additional feature here. For instance, resetting the eeprom or requiring additional keys to be pressed to trigger bootmagic. Keep in mind that `bootmagic_lite` is called before a majority of features are initialized in the firmware. diff --git a/feature_combo.md b/feature_combo.md new file mode 100644 index 00000000000..d831328f698 --- /dev/null +++ b/feature_combo.md @@ -0,0 +1,103 @@ +# Combos + +The Combo feature is a chording type solution for adding custom actions. It lets you hit multiple keys at once and produce a different effect. For instance, hitting `A` and `S` within the tapping term would hit `ESC` instead, or have it perform even more complex tasks. + +To enable this feature, you need to add `COMBO_ENABLE = yes` to your `rules.mk`. + +Additionally, in your `config.h`, you'll need to specify the number of combos that you'll be using, by adding `#define COMBO_COUNT 1` (replacing 1 with the number that you're using). + + +Also, by default, the tapping term for the Combos is set to the same value as `TAPPING_TERM` (200 by default on most boards). But you can specify a different value by defining it in your `config.h`. For instance: `#define COMBO_TERM 300` would set the time out period for combos to 300ms. + +Then, your `keymap.c` file, you'll need to define a sequence of keys, terminated with `COMBO_END`, and a structure to list the combination of keys, and it's resulting action. + +```c +const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END}; +combo_t key_combos[COMBO_COUNT] = {COMBO(test_combo, KC_ESC)}; +``` + +This will send "Escape" if you hit the A and B keys. + +!> This method only supports [basic keycodes](keycodes_basic.md). See the examples for more control. + +## Examples + +If you want to add a list, then you'd use something like this: + +```c +enum combos { + AB_ESC, + JK_TAB +}; + +const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; +const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [AB_ESC] = COMBO(ab_combo, KC_ESC), + [JK_TAB] = COMBO(jk_combo, KC_TAB) +}; +``` + +For a more complicated implementation, you can use the `process_combo_event` function to add custom handling. + +```c +enum combo_events { + ZC_COPY, + XV_PASTE +}; + +const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END}; +const uint16_t PROGMEM paste_combo[] = {KC_X, KC_V, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [ZC_COPY] = COMBO_ACTION(copy_combo), + [XV_PASTE] = COMBO_ACTION(paste_combo), +}; + +void process_combo_event(uint16_t combo_index, bool pressed) { + switch(combo_index) { + case ZC_COPY: + if (pressed) { + tap_code16(LCTL(KC_C)); + } + break; + case XV_PASTE: + if (pressed) { + tap_code16(LCTL(KC_V)); + } + break; + } +} +``` + +This will send Ctrl+C if you hit Z and C, and Ctrl+V if you hit X and V. But you could change this to do stuff like change layers, play sounds, or change settings. + +## Additional Configuration + +If you're using long combos, or even longer combos, you may run into issues with this, as the structure may not be large enough to accommodate what you're doing. + +In this case, you can add either `#define EXTRA_LONG_COMBOS` or `#define EXTRA_EXTRA_LONG_COMBOS` in your `config.h` file. + +You may also be able to enable action keys by defining `COMBO_ALLOW_ACTION_KEYS`. + +## Keycodes + +You can enable, disable and toggle the Combo feature on the fly. This is useful if you need to disable them temporarily, such as for a game. + +|Keycode |Description | +|----------|---------------------------------| +|`CMB_ON` |Turns on Combo feature | +|`CMB_OFF` |Turns off Combo feature | +|`CMB_TOG` |Toggles Combo feature on and off | + +## User callbacks + +In addition to the keycodes, there are a few functions that you can use to set the status, or check it: + +|Function |Description | +|-----------|--------------------------------------------------------------------| +| `combo_enable()` | Enables the combo feature | +| `combo_disable()` | Disables the combo feature, and clears the combo buffer | +| `combo_toggle()` | Toggles the state of the combo feature | +| `is_combo_enabled()` | Returns the status of the combo feature state (true or false) | diff --git a/feature_command.md b/feature_command.md new file mode 100644 index 00000000000..a4ce3f5aea0 --- /dev/null +++ b/feature_command.md @@ -0,0 +1,51 @@ +# Command + +Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic](feature_bootmagic.md). There is a lot of overlap between this functionality and the [Bootmagic Keycodes](feature_bootmagic.md#keycodes). Wherever possible we encourage you to use that feature instead of Command. + +On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`: + +```make +COMMAND_ENABLE = yes +``` + +## Usage + +To use Command, hold down the key combination defined by the `IS_COMMAND()` macro. By default this is Left Shift+Right Shift. Then, press the key corresponding to the command you want. For example, to output the current QMK version to the QMK Toolbox console, press Left Shift+Right Shift+`V`. + +## Configuration + +If you would like to change the key assignments for Command, `#define` these in your `config.h` at either the keyboard or keymap level. All keycode assignments here must omit the `KC_` prefix. + +|Define |Default |Description | +|------------------------------------|--------------------------------|------------------------------------------------| +|`IS_COMMAND()` |`(get_mods() == MOD_MASK_SHIFT)`|The key combination to activate Command | +|`MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` |`true` |Set default layer with the Function row | +|`MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` |`true` |Set default layer with the number keys | +|`MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM`|`false` |Set default layer with `MAGIC_KEY_LAYER0..9` | +|`MAGIC_KEY_DEBUG` |`D` |Toggle debugging over serial | +|`MAGIC_KEY_DEBUG_MATRIX` |`X` |Toggle key matrix debugging | +|`MAGIC_KEY_DEBUG_KBD` |`K` |Toggle keyboard debugging | +|`MAGIC_KEY_DEBUG_MOUSE` |`M` |Toggle mouse debugging | +|`MAGIC_KEY_CONSOLE` |`C` |Enable the Command console | +|`MAGIC_KEY_VERSION` |`V` |Print the running QMK version to the console | +|`MAGIC_KEY_STATUS` |`S` |Print the current keyboard status to the console| +|`MAGIC_KEY_HELP` |`H` |Print Command help to the console | +|`MAGIC_KEY_HELP_ALT` |`SLASH` |Print Command help to the console (alternate) | +|`MAGIC_KEY_LAYER0` |`0` |Make layer 0 the default layer | +|`MAGIC_KEY_LAYER0_ALT` |`GRAVE` |Make layer 0 the default layer (alternate) | +|`MAGIC_KEY_LAYER1` |`1` |Make layer 1 the default layer | +|`MAGIC_KEY_LAYER2` |`2` |Make layer 2 the default layer | +|`MAGIC_KEY_LAYER3` |`3` |Make layer 3 the default layer | +|`MAGIC_KEY_LAYER4` |`4` |Make layer 4 the default layer | +|`MAGIC_KEY_LAYER5` |`5` |Make layer 5 the default layer | +|`MAGIC_KEY_LAYER6` |`6` |Make layer 6 the default layer | +|`MAGIC_KEY_LAYER7` |`7` |Make layer 7 the default layer | +|`MAGIC_KEY_LAYER8` |`8` |Make layer 8 the default layer | +|`MAGIC_KEY_LAYER9` |`9` |Make layer 9 the default layer | +|`MAGIC_KEY_BOOTLOADER` |`B` |Jump to bootloader | +|`MAGIC_KEY_BOOTLOADER_ALT` |`ESC` |Jump to bootloader (alternate) | +|`MAGIC_KEY_LOCK` |`CAPS` |Lock the keyboard so nothing can be typed | +|`MAGIC_KEY_EEPROM` |`E` |Print stored EEPROM config to the console | +|`MAGIC_KEY_EEPROM_CLEAR` |`BSPACE` |Clear the EEPROM | +|`MAGIC_KEY_NKRO` |`N` |Toggle N-Key Rollover (NKRO) | +|`MAGIC_KEY_SLEEP_LED` |`Z` |Toggle LED when computer is sleeping | diff --git a/feature_debounce_type.md b/feature_debounce_type.md new file mode 100644 index 00000000000..966e75acc1f --- /dev/null +++ b/feature_debounce_type.md @@ -0,0 +1,151 @@ +# Contact bounce / contact chatter + +Mechanical switches often don't have a clean single transition between pressed and unpressed states. + +In an ideal world, when you press a switch, you would expect the digital pin to see something like this: +(X axis showing time +``` +voltage +---------------------- + ^ | + | | + | ------------------+ + ----> time +``` + +However in the real world you will actually see contact bounce, which will look like multiple 1->0 and 0->1 transitions, +until the value finally settles. +``` + +-+ +--+ +------------- + | | | | | + | | | | | ++-----------------+ +-+ +-+ +``` +The time it takes for the switch to settle might vary with switch type, age, and even pressing technique. + +If the device chooses not to mitigate contact bounce, then often actions that happen when the switch is pressed are repeated +multiple times. + +There are many ways to handle contact bounce ("Debouncing"). Some include employing additional hardware, for example an RC filter, +while there are various ways to do debouncing in software too, often called debounce algorithms. This page discusses software +debouncing methods available in QMK. + +While technically not considered contact bounce/contact chatter, some switch technologies are susceptible to noise, meaning, +while the key is not changing state, sometimes short random 0->1 or 1->0 transitions might be read by the digital circuit, for example: +``` + +-+ + | | + | | ++-----------------+ +-------------------- +``` + +Many debounce methods (but not all) will also make the device resistant to noise. If you are working with a technology that is +susceptible to noise, you must choose a debounce method that will also mitigate noise for you. + +## Types of debounce algorithms + +1) Unit of time: Timestamp (milliseconds) vs Cycles (scans) + * Debounce algorithms often have a 'debounce time' parameter, that specifies the maximum settling time of the switch contacts. + This time might be measured in various units: + * Cycles-based debouncing waits n cycles (scans), decreasing count by one each matrix_scan + * Timestamp-based debouncing stores the millisecond timestamp a change occurred, and does substraction to figure out time elapsed. + * Timestamp-based debouncing is usually superior, especially in the case of noise-resistant devices because settling times of physical + switches is specified in units of time, and should not depend on the matrix scan-rate of the keyboard. + * Cycles-based debouncing is sometimes considered inferior, because the settling time that it is able to compensate for depends on the + performance of the matrix scanning code. If you use cycles-based debouncing, and you significantly improve the performance of your scanning + code, you might end up with less effective debouncing. A situation in which cycles-based debouncing might be preferable is when + noise is present, and the scanning algorithm is slow, or variable speed. Even if your debounce algorithm is fundamentally noise-resistant, + if the scanning is slow, and you are using a timestamp-based algorithm, you might end up making a debouncing decision based on only two + sampled values, which will limit the noise-resistance of the algorithm. + * Currently all built-in debounce algorithms support timestamp-based debouncing only. In the future we might + implement cycles-based debouncing, and it will be selectable via a ```config.h``` macro. + +2) Symmetric vs Asymmetric + * Symmetric - apply the same debouncing algorithm, to both key-up and key-down events. + * Recommended naming convention: ```sym_*``` + * Asymmetric - apply different debouncing algorithms to key-down and key-up events. E.g. Eager key-down, Defer key-up. + * Recommended naming convention: ```asym_*``` followed by details of the type of algorithm in use, in order, for key-down and then key-up + +3) Eager vs Defer + * Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored. + * Eager algorithms are not noise-resistant. + * Recommended naming conventions: + * ```sym_eager_*``` + * ```asym_eager_*_*```: key-down is using eager algorithm + * ```asym_*_eager_*```: key-up is using eager algorithm + * Defer - wait for no changes for DEBOUNCE ms before reporting change. + * Defer algorithms are noise-resistant + * Recommended naming conventions: + * ```sym_defer_*``` + * ```asym_defer_*_*```: key-down is using defer algorithm + * ```asym_*_defer_*```: key-up is using defer algorithm + +4) Global vs Per-Key vs Per-Row + * Global - one timer for all keys. Any key change state affects global timer + * Recommended naming convention: ```*_g``` + * Per-key - one timer per key + * Recommended naming convention: ```*_pk``` + * Per-row - one timer per row + * Recommended naming convention: ```*_pr``` + * Per-key and per-row algorithms consume more resources (in terms of performance, + and ram usage), but fast typists might prefer them over global. + +## Debounce algorithms supported by QMK + +QMK supports multiple debounce algorithms through its debounce API. +The logic for which debounce method called is below. It checks various defines that you have set in ```rules.mk``` + +``` +DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce +DEBOUNCE_TYPE?= sym_defer_g +ifneq ($(strip $(DEBOUNCE_TYPE)), custom) + QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c +endif +``` + +### Debounce selection + +| DEBOUNCE_TYPE | Description | What else is needed | +| ------------- | --------------------------------------------------- | ----------------------------- | +| Not defined | Use the default algorithm, currently sym_defer_g | Nothing | +| custom | Use your own debounce code | ```SRC += debounce.c``` add your own debounce.c and implement necessary functions | +| Anything Else | Use another algorithm from quantum/debounce/* | Nothing | + +**Regarding split keyboards**: +The debounce code is compatible with split keyboards. + +### Selecting an included debouncing method +Keyboards may select one of the already implemented debounce methods, by adding to ```rules.mk``` the following line: +``` +DEBOUNCE_TYPE = +``` +Where name of algorithm is one of: +* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed. + * This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant. +* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row. +For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be +appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use. +* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key +* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed. + +### A couple algorithms that could be implemented in the future: +* ```sym_defer_pr``` +* ```sym_eager_g``` +* ```asym_eager_defer_pk``` + +### Use your own debouncing code +You have the option to implement you own debouncing algorithm. To do this: +* Set ```DEBOUNCE_TYPE = custom``` in ```rules.mk```. +* Add ```SRC += debounce.c``` in ```rules.mk``` +* Add your own ```debounce.c```. Look at current implementations in ```quantum/debounce``` for examples. +* Debouncing occurs after every raw matrix scan. +* Use num_rows rather than MATRIX_ROWS, so that split keyboards are supported correctly. +* If the algorithm might be applicable to other keyboards, please consider adding it to ```quantum/debounce``` + +### Old names +The following old names for existing algorithms will continue to be supported, however it is recommended to use the new names instead. + +* sym_g - old name for sym_defer_g +* eager_pk - old name for sym_eager_pk +* sym_pk - old name for sym_defer_pk +* eager_pr - old name for sym_eager_pr + diff --git a/feature_dip_switch.md b/feature_dip_switch.md new file mode 100644 index 00000000000..15e449c4c46 --- /dev/null +++ b/feature_dip_switch.md @@ -0,0 +1,104 @@ +# DIP Switches + +DIP switches are supported by adding this to your `rules.mk`: + + DIP_SWITCH_ENABLE = yes + +and this to your `config.h`: + +```c +// Connects each switch in the dip switch to the GPIO pin of the MCU +#define DIP_SWITCH_PINS { B14, A15, A10, B9 } +``` + +or + +```c +// Connect each switch in the DIP switch to an unused intersections in the key matrix. +#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs +``` + +## Callbacks + +The callback functions can be inserted into your `.c`: + +```c +void dip_switch_update_kb(uint8_t index, bool active) { + dip_switch_update_user(index, active); +} +``` + + +or `keymap.c`: + +```c +void dip_switch_update_user(uint8_t index, bool active) { + switch (index) { + case 0: + if(active) { audio_on(); } else { audio_off(); } + break; + case 1: + if(active) { clicky_on(); } else { clicky_off(); } + break; + case 2: + if(active) { music_on(); } else { music_off(); } + break; + case 3: + if (active) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_song); + #endif + layer_on(_PLOVER); + } else { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + break; + } +} +``` + +Additionally, we support bit mask functions which allow for more complex handling. + + +```c +void dip_switch_update_mask_kb(uint32_t state) { + dip_switch_update_mask_user(state); +} +``` + + +or `keymap.c`: + +```c +void dip_switch_update_mask_user(uint32_t state) { + if (state & (1UL<<0) && state & (1UL<<1)) { + layer_on(_ADJUST); // C on esc + } else { + layer_off(_ADJUST); + } + if (state & (1UL<<0)) { + layer_on(_TEST_A); // A on ESC + } else { + layer_off(_TEST_A); + } + if (state & (1UL<<1)) { + layer_on(_TEST_B); // B on esc + } else { + layer_off(_TEST_B); + } +} +``` + + +## Hardware + +### Connects each switch in the dip switch to the GPIO pin of the MCU + +One side of the DIP switch should be wired directly to the pin on the MCU, and the other side to ground. It should not matter which side is connected to which, as it should be functionally the same. + +### Connect each switch in the DIP switch to an unused intersections in the key matrix. + +As with the keyswitch, a diode and DIP switch connect the ROW line to the COL line. diff --git a/feature_dynamic_macros.md b/feature_dynamic_macros.md new file mode 100644 index 00000000000..01f2a0ca407 --- /dev/null +++ b/feature_dynamic_macros.md @@ -0,0 +1,66 @@ +# Dynamic Macros: Record and Replay Macros in Runtime + +QMK supports temporary macros created on the fly. We call these Dynamic Macros. They are defined by the user from the keyboard and are lost when the keyboard is unplugged or otherwise rebooted. + +You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM. + +To enable them, first include `DYNAMIC_MACRO_ENABLE = yes` in your `rules.mk`. Then, add the following keys to your keymap: + +|Key |Alias |Description | +|------------------|----------|---------------------------------------------------| +|`DYN_REC_START1` |`DM_REC1` |Start recording Macro 1 | +|`DYN_REC_START2` |`DM_REC2` |Start recording Macro 2 | +|`DYN_MACRO_PLAY1` |`DM_PLY1` |Replay Macro 1 | +|`DYN_MACRO_PLAY2` |`DM_PLY2` |Replay Macro 2 | +|`DYN_REC_STOP` |`DM_RSTP` |Finish the macro that is currently being recorded. | + +That should be everything necessary. + +To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. + +To finish the recording, press the `DYN_REC_STOP` layer button. You can also press `DYN_REC_START1` or `DYN_REC_START2` again to stop the recording. + +To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`. + +It is possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. You can disable this completely by defining `DYNAMIC_MACRO_NO_NESTING` in your `config.h` file. + +?> For the details about the internals of the dynamic macros, please read the comments in the `process_dynamic_macro.h` and `process_dynamic_macro.c` files. + +## Customization + +There are a number of options added that should allow some additional degree of customization + +|Define |Default |Description | +|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| +|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. | +|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. | +|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). | + + +If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header). + + +### DYNAMIC_MACRO_USER_CALL + +For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, add `#define DYNAMIC_MACRO_USER_CALL` to your `config.h` and insert the following snippet at the beginning of your `process_record_user()` function: + +```c + uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode); + + if (!process_record_dynamic_macro(macro_kc, record)) { + return false; + } +``` + +### User Hooks + +There are a number of hooks that you can use to add custom functionality and feedback options to Dynamic Macro feature. This allows for some additional degree of customization. + +Note, that direction indicates which macro it is, with `1` being Macro 1, `-1` being Macro 2, and 0 being no macro. + +* `dynamic_macro_record_start_user(void)` - Triggered when you start recording a macro. +* `dynamic_macro_play_user(int8_t direction)` - Triggered when you play back a macro. +* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - Triggered on each keypress while recording a macro. +* `dynamic_macro_record_end_user(int8_t direction)` - Triggered when the macro recording is stopped. + +Additionally, you can call `dynamic_macro_led_blink()` to flash the backlights if that feature is enabled. diff --git a/feature_encoders.md b/feature_encoders.md new file mode 100644 index 00000000000..8f9ba1a80a7 --- /dev/null +++ b/feature_encoders.md @@ -0,0 +1,76 @@ +# Encoders + +Basic encoders are supported by adding this to your `rules.mk`: + +```make +ENCODER_ENABLE = yes +``` + +and this to your `config.h`: + +```c +#define ENCODERS_PAD_A { B12 } +#define ENCODERS_PAD_B { B13 } +``` + +Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.: + +```c +#define ENCODERS_PAD_A { encoder1a, encoder2a } +#define ENCODERS_PAD_B { encoder1b, encoder2b } +``` + +If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions. They can also be flipped with a define: + +```c +#define ENCODER_DIRECTION_FLIP +``` + +Additionally, the resolution, which defines how many pulses the encoder registers between each detent, can be defined with: + +```c +#define ENCODER_RESOLUTION 4 +``` + +## Split Keyboards + +If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout for the right half like this: + +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + +## Callbacks + +The callback functions can be inserted into your `.c`: + +```c +void encoder_update_kb(uint8_t index, bool clockwise) { + encoder_update_user(index, clockwise); +} +``` + +or `keymap.c`: + +```c +void encoder_update_user(uint8_t index, bool clockwise) { + if (index == 0) { /* First encoder */ + if (clockwise) { + tap_code(KC_PGDN); + } else { + tap_code(KC_PGUP); + } + } else if (index == 1) { /* Second encoder */ + if (clockwise) { + tap_code(KC_DOWN); + } else { + tap_code(KC_UP); + } + } +} +``` + +## Hardware + +The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground. diff --git a/feature_grave_esc.md b/feature_grave_esc.md new file mode 100644 index 00000000000..f57c6042ca5 --- /dev/null +++ b/feature_grave_esc.md @@ -0,0 +1,32 @@ +# Grave Escape + +If you're using a 60% keyboard, or any other layout with no F-row, you will have noticed that there is no dedicated Escape key. Grave Escape is a feature that allows you to share the grave key (` and `~`) with Escape. + +## Usage + +Replace the `KC_GRAVE` key in your keymap (usually to the left of the `1` key) with `KC_GESC`. Most of the time this key will output `KC_ESC` when pressed. However, when Shift or GUI are held down it will output `KC_GRV` instead. + +## What Your OS Sees + +If Mary presses GESC on her keyboard, the OS will see an KC_ESC character. Now if Mary holds Shift down and presses GESC it will output `~`, or a shifted backtick. Now if she holds GUI/CMD/WIN, it will output a simple ` character. + +## Keycodes + +|Key |Aliases |Description | +|---------|-----------|------------------------------------------------------------------| +|`KC_GESC`|`GRAVE_ESC`|Escape when pressed, ` when Shift or GUI are held| + +### Caveats + +On macOS, Command+` is by default mapped to "Move focus to next window" so it will not output a backtick. Additionally, Terminal always recognises this shortcut to cycle between windows, even if the shortcut is changed in the Keyboard preferences. + +## Configuration + +There are several possible key combinations this will break, among them Control+Shift+Escape on Windows and Command+Option+Escape on macOS. To work around this, you can `#define` these options in your `config.h`: + +|Define |Description | +|--------------------------|-----------------------------------------| +|`GRAVE_ESC_ALT_OVERRIDE` |Always send Escape if Alt is pressed | +|`GRAVE_ESC_CTRL_OVERRIDE` |Always send Escape if Control is pressed | +|`GRAVE_ESC_GUI_OVERRIDE` |Always send Escape if GUI is pressed | +|`GRAVE_ESC_SHIFT_OVERRIDE`|Always send Escape if Shift is pressed | diff --git a/feature_haptic_feedback.md b/feature_haptic_feedback.md new file mode 100644 index 00000000000..ff7337a51a4 --- /dev/null +++ b/feature_haptic_feedback.md @@ -0,0 +1,158 @@ +# Haptic Feedback + +## Haptic feedback rules.mk options + +The following options are currently available for haptic feedback in `rules.mk`: + +`HAPTIC_ENABLE += DRV2605L` + +`HAPTIC_ENABLE += SOLENOID` + +## Known Supported Hardware + +| Name | Description | +|--------------------|-------------------------------------------------| +| [LV061228B-L65-A](https://www.digikey.com/product-detail/en/jinlong-machinery-electronics-inc/LV061228B-L65-A/1670-1050-ND/7732325) | z-axis 2v LRA | +| [Mini Motor Disc](https://www.adafruit.com/product/1201) | small 2-5v ERM | + +## Haptic Keycodes + +Not all keycodes below will work depending on which haptic mechanism you have chosen. + +| Name | Description | +|-----------|-------------------------------------------------------| +|`HPT_ON` | Turn haptic feedback on | +|`HPT_OFF` | Turn haptic feedback off | +|`HPT_TOG` | Toggle haptic feedback on/off | +|`HPT_RST` | Reset haptic feedback config to default | +|`HPT_FBK` | Toggle feedback to occur on keypress, release or both | +|`HPT_BUZ` | Toggle solenoid buzz on/off | +|`HPT_MODI` | Go to next DRV2605L waveform | +|`HPT_MODD` | Go to previous DRV2605L waveform | +|`HPT_CONT` | Toggle continuous haptic mode on/off | +|`HPT_CONI` | Increase DRV2605L continous haptic strength | +|`HPT_COND` | Decrease DRV2605L continous haptic strength | +|`HPT_DWLI` | Increase Solenoid dwell time | +|`HPT_DWLD` | Decrease Solenoid dwell time | + +### Solenoids + +First you will need a build a circuit to drive the solenoid through a mosfet as most MCU will not be able to provide the current needed to drive the coil in the solenoid. + +[Wiring diagram provided by Adafruit](https://playground.arduino.cc/uploads/Learning/solenoid_driver.pdf) + + +| Settings | Default | Description | +|--------------------------|---------------|-------------------------------------------------------| +|`SOLENOID_PIN` | *Not defined* |Configures the pin that the Solenoid is connected to. | +|`SOLENOID_DEFAULT_DWELL` | `12` ms |Configures the default dwell time for the solenoid. | +|`SOLENOID_MIN_DWELL` | `4` ms |Sets the lower limit for the dwell. | +|`SOLENOID_MAX_DWELL` | `100` ms |Sets the upper limit for the dwell. | + +?> Dwell time is how long the "plunger" stays activated. The dwell time changes how the solenoid sounds. + +Beware that some pins may be powered during bootloader (ie. A13 on the STM32F303 chip) and will result in the solenoid kept in the on state through the whole flashing process. This may overheat and damage the solenoid. If you find that the pin the solenoid is connected to is triggering the solenoid during bootloader/DFU, select another pin. + +### DRV2605L + +DRV2605L is controlled over i2c protocol, and has to be connected to the SDA and SCL pins, these varies depending on the MCU in use. + +#### Feedback motor setup + +This driver supports 2 different feedback motors. Set the following in your `config.h` based on which motor you have selected. + +##### ERM + +Eccentric Rotating Mass vibration motors (ERM) is motor with a off-set weight attached so when drive signal is attached, the off-set weight spins and causes a sinusoidal wave that translate into vibrations. + +``` +#define FB_ERM_LRA 0 +#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ +#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ + +/* Please refer to your datasheet for the optimal setting for your specific motor. */ +#define RATED_VOLTAGE 3 +#define V_PEAK 5 +``` +##### LRA + +Linear resonant actuators (LRA, also know as a linear vibrator) works different from a ERM. A LRA has a weight and magnet suspended by springs and a voice coil. When the drive signal is applied, the weight would be vibrate on a single axis (side to side or up and down). Since the weight is attached to a spring, there is a resonance effect at a specific frequency. This frequency is where the LRA will operate the most efficiently. Refer to the motor's datasheet for the recommanded range for this frequency. + +``` +#define FB_ERM_LRA 1 +#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ +#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ + +/* Please refer to your datasheet for the optimal setting for your specific motor. */ +#define RATED_VOLTAGE 2 +#define V_PEAK 2.8 +#define V_RMS 2.0 +#define V_PEAK 2.1 +#define F_LRA 205 /* resonance freq */ +``` + +#### DRV2605L waveform library + +DRV2605L comes with preloaded library of various waveform sequences that can be called and played. If writing a macro, these waveforms can be played using `DRV_pulse(*sequence name or number*)` + +List of waveform sequences from the datasheet: + +|seq# | Sequence name |seq# | Sequence name |seq# |Sequence name | +|-----|---------------------|-----|-----------------------------------|-----|--------------------------------------| +| 1 | strong_click | 43 | lg_dblclick_med_60 | 85 | transition_rampup_med_smooth2 | +| 2 | strong_click_60 | 44 | lg_dblsharp_tick | 86 | transition_rampup_short_smooth1 | +| 3 | strong_click_30 | 45 | lg_dblsharp_tick_80 | 87 | transition_rampup_short_smooth2 | +| 4 | sharp_click | 46 | lg_dblsharp_tick_60 | 88 | transition_rampup_long_sharp1 | +| 5 | sharp_click_60 | 47 | buzz | 89 | transition_rampup_long_sharp2 | +| 6 | sharp_click_30 | 48 | buzz_80 | 90 | transition_rampup_med_sharp1 | +| 7 | soft_bump | 49 | buzz_60 | 91 | transition_rampup_med_sharp2 | +| 8 | soft_bump_60 | 50 | buzz_40 | 92 | transition_rampup_short_sharp1 | +| 9 | soft_bump_30 | 51 | buzz_20 | 93 | transition_rampup_short_sharp2 | +| 10 | dbl_click | 52 | pulsing_strong | 94 | transition_rampdown_long_smooth1_50 | +| 11 | dbl_click_60 | 53 | pulsing_strong_80 | 95 | transition_rampdown_long_smooth2_50 | +| 12 | trp_click | 54 | pulsing_medium | 96 | transition_rampdown_med_smooth1_50 | +| 13 | soft_fuzz | 55 | pulsing_medium_80 | 97 | transition_rampdown_med_smooth2_50 | +| 14 | strong_buzz | 56 | pulsing_sharp | 98 | transition_rampdown_short_smooth1_50 | +| 15 | alert_750ms | 57 | pulsing_sharp_80 | 99 | transition_rampdown_short_smooth2_50 | +| 16 | alert_1000ms | 58 | transition_click | 100 | transition_rampdown_long_sharp1_50 | +| 17 | strong_click1 | 59 | transition_click_80 | 101 | transition_rampdown_long_sharp2_50 | +| 18 | strong_click2_80 | 60 | transition_click_60 | 102 | transition_rampdown_med_sharp1_50 | +| 19 | strong_click3_60 | 61 | transition_click_40 | 103 | transition_rampdown_med_sharp2_50 | +| 20 | strong_click4_30 | 62 | transition_click_20 | 104 | transition_rampdown_short_sharp1_50 | +| 21 | medium_click1 | 63 | transition_click_10 | 105 | transition_rampdown_short_sharp2_50 | +| 22 | medium_click2_80 | 64 | transition_hum | 106 | transition_rampup_long_smooth1_50 | +| 23 | medium_click3_60 | 65 | transition_hum_80 | 107 | transition_rampup_long_smooth2_50 | +| 24 | sharp_tick1 | 66 | transition_hum_60 | 108 | transition_rampup_med_smooth1_50 | +| 25 | sharp_tick2_80 | 67 | transition_hum_40 | 109 | transition_rampup_med_smooth2_50 | +| 26 | sharp_tick3_60 | 68 | transition_hum_20 | 110 | transition_rampup_short_smooth1_50 | +| 27 | sh_dblclick_str | 69 | transition_hum_10 | 111 | transition_rampup_short_smooth2_50 | +| 28 | sh_dblclick_str_80 | 70 | transition_rampdown_long_smooth1 | 112 | transition_rampup_long_sharp1_50 | +| 29 | sh_dblclick_str_60 | 71 | transition_rampdown_long_smooth2 | 113 | transition_rampup_long_sharp2_50 | +| 30 | sh_dblclick_str_30 | 72 | transition_rampdown_med_smooth1 | 114 | transition_rampup_med_sharp1_50 | +| 31 | sh_dblclick_med | 73 | transition_rampdown_med_smooth2 | 115 | transition_rampup_med_sharp2_50 | +| 32 | sh_dblclick_med_80 | 74 | transition_rampdown_short_smooth1 | 116 | transition_rampup_short_sharp1_50 | +| 33 | sh_dblclick_med_60 | 75 | transition_rampdown_short_smooth2 | 117 | transition_rampup_short_sharp2_50 | +| 34 | sh_dblsharp_tick | 76 | transition_rampdown_long_sharp1 | 118 | long_buzz_for_programmatic_stopping | +| 35 | sh_dblsharp_tick_80 | 77 | transition_rampdown_long_sharp2 | 119 | smooth_hum1_50 | +| 36 | sh_dblsharp_tick_60 | 78 | transition_rampdown_med_sharp1 | 120 | smooth_hum2_40 | +| 37 | lg_dblclick_str | 79 | transition_rampdown_med_sharp2 | 121 | smooth_hum3_30 | +| 38 | lg_dblclick_str_80 | 80 | transition_rampdown_short_sharp1 | 122 | smooth_hum4_20 | +| 39 | lg_dblclick_str_60 | 81 | transition_rampdown_short_sharp2 | 123 | smooth_hum5_10 | +| 40 | lg_dblclick_str_30 | 82 | transition_rampup_long_smooth1 | | | +| 41 | lg_dblclick_med | 83 | transition_rampup_long_smooth2 | | | +| 42 | lg_dblclick_med_80 | 84 | transition_rampup_med_smooth1 | | | +### Optional DRV2605L defines + +``` +#define DRV_GREETING *sequence name or number* +``` +If haptic feedback is enabled, the keyboard will vibrate to a specific sqeuence during startup. That can be selected using the following define: + +``` +#define DRV_MODE_DEFAULT *sequence name or number* +``` +This will set what sequence HPT_RST will set as the active mode. If not defined, mode will be set to 1 when HPT_RST is pressed. + +### DRV2605L Continuous Haptic Mode + +This mode sets continuous haptic feedback with the option to increase or decrease strength. diff --git a/feature_hd44780.md b/feature_hd44780.md new file mode 100644 index 00000000000..dc476c734f8 --- /dev/null +++ b/feature_hd44780.md @@ -0,0 +1,57 @@ +# HD44780 LCD Displays + +This is an integration of Peter Fleury's LCD library. This page will explain the basics. [For in depth documentation visit his page.](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) + +You can enable support for HD44780 Displays by setting the `HD44780_ENABLE` flag in your keyboards `rules.mk` to yes. + +## Configuration + +You will need to configure the pins used by your display, and its number of lines and columns in your keyboard's `config.h`. + + +Uncomment the section labled HD44780 and change the parameters as needed. +```` +/* + * HD44780 LCD Display Configuration + */ + +#define LCD_LINES 2 //< number of visible lines of the display +#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display +#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode +#if LCD_IO_MODE +#define LCD_PORT PORTB //< port for the LCD lines +#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0 +#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1 +#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2 +#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3 +#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0 +#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1 +#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2 +#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3 +#define LCD_RS_PORT LCD_PORT //< port for RS line +#define LCD_RS_PIN 3 //< pin for RS line +#define LCD_RW_PORT LCD_PORT //< port for RW line +#define LCD_RW_PIN 2 //< pin for RW line +#define LCD_E_PORT LCD_PORT //< port for Enable line +#define LCD_E_PIN 1 //< pin for Enable line +#endif +```` + +Should you need to configure other properties you can copy them from `quantum/hd44780.h` and set them in your `config.h` + +## Usage + +To initialize your display, call `lcd_init()` with one of these parameters: +```` +LCD_DISP_OFF : display off +LCD_DISP_ON : display on, cursor off +LCD_DISP_ON_CURSOR : display on, cursor on +LCD_DISP_ON_CURSOR_BLINK : display on, cursor on flashing +```` +This is best done in your keyboards `matrix_init_kb` or your keymaps `matrix_init_user`. +It is advised to clear the display before use. +To do so call `lcd_clrscr()`. + +To now print something to your Display you first call `lcd_gotoxy(column, line)`. To go to the start of the first line you would call `lcd_gotoxy(0, 0)` and then print a string with `lcd_puts("example string")`. + +There are more methods available to control the display. [For in depth documentation please visit the linked page.](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) diff --git a/feature_joystick.md b/feature_joystick.md new file mode 100644 index 00000000000..be3c781f6cd --- /dev/null +++ b/feature_joystick.md @@ -0,0 +1,147 @@ +## Joystick + +The keyboard can be made to be recognized as a joystick HID device by the operating system. + +This is enabled by adding `JOYSTICK_ENABLE` to `rules.mk`. You can set this value to `analog`, `digital`, or `no`. + +!> Joystick support is not currently available on V-USB devices. + +The joystick feature provides two services: + * reading analog input devices (eg. potentiometers) + * sending gamepad HID reports + +Both services can be used without the other, depending on whether you just want to read a device but not send gamepad reports (for volume control for instance) +or send gamepad reports based on values computed by the keyboard. + +### Analog Input + +To use analog input you must first enable it in `rules.mk`: + +```makefile +JOYSTICK_ENABLE = analog +``` + +An analog device such as a potentiometer found on a gamepad's analog axes is based on a [voltage divider](https://en.wikipedia.org/wiki/Voltage_divider). +It is composed of three connectors linked to the ground, the power input and power output (usually the middle one). The power output holds the voltage that varies based on the position of the cursor, +which value will be read using your MCU's [ADC](https://en.wikipedia.org/wiki/Analog-to-digital_converter). +Depending on which pins are already used by your keyboard's matrix, the rest of the circuit can get a little bit more complicated, +feeding the power input and ground connection through pins and using diodes to avoid bad interactions with the matrix scanning procedures. + +### Configuring the Joystick + +By default, two axes and eight buttons are defined. This can be changed in your `config.h`: + +```c +// Max 32 +#define JOYSTICK_BUTTON_COUNT 16 +// Max 6: X, Y, Z, Rx, Ry, Rz +#define JOYSTICK_AXES_COUNT 3 +``` + +When defining axes for your joystick, you have to provide a definition array. You can do this from your keymap.c file. +A joystick will either be read from an input pin that allows the use of the ADC, or can be virtual, so that its value is provided by your code. +You have to define an array of type ''joystick_config_t'' and of proper size. + +There are three ways for your circuit to work with the ADC, that relies on the use of 1, 2 or 3 pins of the MCU: + * 1 pin: your analog device is directly connected to your device GND and VCC. The only pin used is the ADC pin of your choice. + * 2 pins: your analog device is powered through a pin that allows toggling it on or off. The other pin is used to read the input value through the ADC. + * 3 pins: both the power input and ground are connected to pins that must be set to a proper state before reading and restored afterwards. + +The configuration of each axis is performed using one of four macros: + * `JOYSTICK_AXIS_VIRTUAL`: no ADC reading must be performed, that value will be provided by keyboard/keymap-level code + * `JOYSTICK_AXIS_IN(INPUT_PIN, LOW, REST, HIGH)`: a voltage will be read on the provided pin, which must be an ADC-capable pin. + * `JOYSTICK_AXIS_IN_OUT(INPUT_PIN, OUTPUT_PIN, LOW, REST, HIGH)`: the provided `OUTPUT_PIN` will be set high before `INPUT_PIN` is read. + * `JOYSTICK_AXIS_IN_OUT_GROUND(INPUT_PIN, OUTPUT_PIN, GROUND_PIN, LOW, REST, HIGH)`: the `OUTPUT_PIN` will be set high and `GROUND_PIN` will be set low before reading from `INPUT_PIN`. + +In any case where an ADC reading takes place (when `INPUT_PIN` is provided), additional `LOW`, `REST` and `HIGH` parameters are used. +These implement the calibration of the analog device by defining the range of read values that will be mapped to the lowest, resting position and highest possible value for the axis (-127 to 127). +In practice, you have to provide the lowest/highest raw ADC reading, and the raw reading at resting position, when no deflection is applied. You can provide inverted `LOW` and `HIGH` to invert the axis. + +For instance, an axes configuration can be defined in the following way: + +```c +//joystick config +joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT] = { + [0] = JOYSTICK_AXIS_IN_OUT_GROUND(A4, B0, A7, 900, 575, 285), + [1] = JOYSTICK_AXIS_VIRTUAL +}; +``` + +When the ADC reads 900 or higher, the returned axis value will be -127, whereas it will be 127 when the ADC reads 285 or lower. Zero is returned when 575 is read. + +In this example, the first axis will be read from the `A4` pin while `B0` is set high and `A7` is set low, using `analogReadPin()`, whereas the second axis will not be read. + +In order to give a value to the second axis, you can do so in any customizable entry point: as an action, in `process_record_user()` or in `matrix_scan_user()`, or even in `joystick_task()` which is called even when no key has been pressed. +You assign a value by writing to `joystick_status.axes[axis_index]` a signed 8-bit value (ranging from -127 to 127). Then it is necessary to assign the flag `JS_UPDATED` to `joystick_status.status` in order for an updated HID report to be sent. + +The following example writes two axes based on keypad presses, with `KC_P5` as a precision modifier: + +```c +#ifdef ANALOG_JOYSTICK_ENABLE +static uint8_t precision_val = 70; +static uint8_t axesFlags = 0; +enum axes { + Precision = 1, + Axis1High = 2, + Axis1Low = 4, + Axis2High = 8, + Axis2Low = 16 +}; +#endif + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { +#ifdef ANALOG_JOYSTICK_ENABLE + // virtual joystick +# if JOYSTICK_AXES_COUNT > 1 + case KC_P8: + if (record->event.pressed) { + axesFlags |= Axis2Low; + } else { + axesFlags &= ~Axis2Low; + } + joystick_status.status |= JS_UPDATED; + break; + case KC_P2: + if (record->event.pressed) { + axesFlags |= Axis2High; + } else { + axesFlags &= ~Axis2High; + } + joystick_status.status |= JS_UPDATED; + break; +# endif + case KC_P4: + if (record->event.pressed) { + axesFlags |= Axis1Low; + } else { + axesFlags &= ~Axis1Low; + } + joystick_status.status |= JS_UPDATED; + break; + case KC_P6: + if (record->event.pressed) { + axesFlags |= Axis1High; + } else { + axesFlags &= ~Axis1High; + } + joystick_status.status |= JS_UPDATED; + break; + case KC_P5: + if (record->event.pressed) { + axesFlags |= Precision; + } else { + axesFlags &= ~Precision; + } + joystick_status.status |= JS_UPDATED; + break; +#endif + } + return true; +} +``` + +### Triggering Joystick Buttons + +Joystick buttons are normal Quantum keycodes, defined as `JS_BUTTON0` to `JS_BUTTON31`, depending on the number of buttons you have configured. +To trigger a joystick button, just add the corresponding keycode to your keymap. diff --git a/feature_key_lock.md b/feature_key_lock.md new file mode 100644 index 00000000000..8e6e29f0e68 --- /dev/null +++ b/feature_key_lock.md @@ -0,0 +1,22 @@ +# Key Lock + +Sometimes you may find yourself needing to hold down a specific key for a long period of time. Key Lock holds down the next key you press for you. Press it again, and it will be released. + +Let's say you need to type in ALL CAPS for a few sentences. Hit `KC_LOCK`, and then Shift. Now, Shift will be considered held until you tap it again. You can think of Key Lock as Caps Lock, but supercharged. + +## Usage + +First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Then pick a key in your keymap and assign it the keycode `KC_LOCK`. + +## Keycodes + +|Keycode |Description | +|---------|--------------------------------------------------------------| +|`KC_LOCK`|Hold down the next key pressed, until the key is pressed again| + +## Caveats + +Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`). +This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held. + +Switching layers will not cancel the Key Lock. diff --git a/feature_layers.md b/feature_layers.md new file mode 100644 index 00000000000..3f62cfc805a --- /dev/null +++ b/feature_layers.md @@ -0,0 +1,93 @@ +# Layers :id=layers + +One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard. + +For a detailed explanation of how the layer stack works, checkout [Keymap Overview](keymap.md#keymap-and-layers). + +## Switching and Toggling Layers :id=switching-and-toggling-layers + +These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended. + +* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions.md#programming-the-behavior-of-any-keycode).) +* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated. +* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15 and the left modifiers: `MOD_LCTL`, `MOD_LSFT`, `MOD_LALT`, `MOD_LGUI` (note the use of `MOD_` constants instead of `KC_`). These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`. +* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15. +* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys.md) for details and additional functionality. +* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa +* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed). +* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps. + +### Caveats :id=caveats + +Currently, `LT()` and `MT()` are limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. Specifically, dual function keys like `LT` and `MT` use a 16 bit keycode. 4 bits are used for the function identifier, the next 12 are divided into the parameters. Layer Tap uses 4 bits for the layer (and is why it's limited to layers 0-15, actually), while Mod Tap does the same, 4 bits for the identifier, 4 bits for which mods are used, and all of them use 8 bits for the keycode. Because of this, the keycode used is limited to `0xFF` (0-255), which are the basic keycodes only. + +Expanding this would be complicated, at best. Moving to a 32-bit keycode would solve a lot of this, but would double the amount of space that the keymap matrix uses. And it could potentially cause issues, too. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this. + +Additionally, if at least one right-handed modifier is specified in a Mod Tap or Layer Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two. + +## Working with Layers :id=working-with-layers + +Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems. + +### Beginners :id=beginners + +If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers: + +* Setup layer 0 as your default, "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.). It's important to set this as the lowest layer since it will typically have most or all of the keyboard's keys defined, so would block other layers from having any effect if it were above them (i.e., had a higher layer number). +* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer. +* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone. + +### Intermediate Users :id=intermediate-users + +Sometimes you need more than one base layer. For example, if you want to switch between QWERTY and Dvorak, switch between layouts for different countries, or switch your layout for different videogames. Your base layers should always be the lowest numbered layers. When you have multiple base layers you should always treat them as mutually exclusive. When one base layer is on the others are off. + +### Advanced Users :id=advanced-users + +Once you have a good feel for how layers work and what you can do, you can get more creative. The rules listed in the beginner section will help you be successful by avoiding some of the tricker details but they can be constraining, especially for ultra-compact keyboard users. Understanding how layers work will allow you to use them in more advanced ways. + +Layers stack on top of each other in numerical order. When determining what a keypress does, QMK scans the layers from the top down, stopping when it reaches the first active layer that is not set to `KC_TRNS`. As a result if you activate a layer that is numerically lower than your current layer, and your current layer (or another layer that is active and higher than your target layer) has something other than `KC_TRNS`, that is the key that will be sent, not the key on the layer you just activated. This is the cause of most people's "why doesn't my layer get switched" problem. + +Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_layer.h). + +## Functions :id=functions + +There are a number of functions (and variables) related to how you can use or manipulate the layers. + +|Function |Description | +|----------------------------------------------|---------------------------------------------------------------------------------------------------------| +| `layer_state_set(layer_mask)` | Directly sets the layer state (recommended, do not use unless you know what you are doing). | +| `layer_clear()` | Clears all layers (turns them all off). | +| `layer_move(layer)` | Turns specified layer on, and all other layers off. | +| `layer_on(layer)` | Turns specified layer on, leaves all other layers in existing state. | +| `layer_off(layer)` | Turns specified layer off, leaves all other layers in existing state. | +| `layer_invert(layer)` | Interverts/toggles the state of the specified layer | +| `layer_or(layer_mask)` | Turns on layers based on matching bits between specifed layer and existing layer state. | +| `layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing layer state. | +| `layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing layer state. | +| `layer_debug(layer_mask)` | Prints out the current bit mask and highest active layer to debugger console. | +| `default_layer_set(layer_mask)` | Directly sets the default layer state (recommended, do not use unless you know what you are doing). | +| `default_layer_or(layer_mask)` | Turns on layers based on matching bits between specifed layer and existing default layer state. | +| `default_layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing default layer state. | +| `default_layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing default layer state. | +| `default_layer_debug(layer_mask)` | Prints out the current bit mask and highest active default layer to debugger console. | +| [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer) | Sets the default layer and writes it to persistent memory (EEPROM). | +| [`update_tri_layer(x, y, z)`](ref_functions.md#update_tri_layerx-y-z) | Checks if layers `x` and `y` are both on, and sets `z` based on that (on if both on, otherwise off). | +| [`update_tri_layer_state(state, x, y, z)`](ref_functions.md#update_tri_layer_statestate-x-y-z) | Does the same as `update_tri_layer(x, y, z)`, but from `layer_state_set_*` functions. | + +In addition to the functions that you can call, there are a number of callback functions that get called every time the layer changes. This passes the layer state to the function, where it can be read or modified. + +|Callback |Description | +|-----------------------------------------------------|----------------------------------------------------------------------------------------| +| `layer_state_set_kb(layer_state_t state)` | Callback for layer functions, for keyboard. | +| `layer_state_set_user(layer_state_t state)` | Callback for layer functions, for users. | +| `default_layer_state_set_kb(layer_state_t state)` | Callback for default layer functions, for keyboard. Called on keyboard initialization. | +| `default_layer_state_set_user(layer_state_t state)` | Callback for default layer functions, for users. Called on keyboard initialization. | + +?> For additional details on how you can use these callbacks, check out the [Layer Change Code](custom_quantum_functions.md#layer-change-code) document. + +It is also possible to check the state of a particular layer using the following functions and macros. + +|Function |Description |Aliases +|---------------------------------|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------| +| `layer_state_is(layer)` | Checks if the specified `layer` is enabled globally. | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` | +| `layer_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` | diff --git a/feature_layouts.md b/feature_layouts.md new file mode 100644 index 00000000000..b34fd442d5c --- /dev/null +++ b/feature_layouts.md @@ -0,0 +1,109 @@ +# Layouts: Using a Keymap with Multiple Keyboards + +The `layouts/` folder contains different physical key layouts that can apply to different keyboards. + +``` +layouts/ ++ default/ +| + 60_ansi/ +| | + readme.md +| | + layout.json +| | + a_good_keymap/ +| | | + keymap.c +| | | + readme.md +| | | + config.h +| | | + rules.mk +| | + / +| | + ... +| + / ++ community/ +| + / +| + ... +``` + +The `layouts/default/` and `layouts/community/` are two examples of layout "repositories" - currently `default` will contain all of the information concerning the layout, and one default keymap named `default_`, for users to use as a reference. `community` contains all of the community keymaps, with the eventual goal of being split-off into a separate repo for users to clone into `layouts/`. QMK searches through all folders in `layouts/`, so it's possible to have multiple repositories here. + +Each layout folder is named (`[a-z0-9_]`) after the physical aspects of the layout, in the most generic way possible, and contains a `readme.md` with the layout to be defined by the keyboard: + +```md +# 60_ansi + + LAYOUT_60_ansi +``` + +New names should try to stick to the standards set by existing layouts, and can be discussed in the PR/Issue. + +## Supporting a Layout + +For a keyboard to support a layout, the variable must be defined in it's `.h`, and match the number of arguments/keys (and preferably the physical layout): + + #define LAYOUT_60_ansi KEYMAP_ANSI + +The name of the layout must match this regex: `[a-z0-9_]+` + +The folder name must be added to the keyboard's `rules.mk`: + + LAYOUTS = 60_ansi + +`LAYOUTS` can be set in any keyboard folder level's `rules.mk`: + + LAYOUTS = 60_iso + +but the `LAYOUT_` variable must be defined in `.h` as well. + +## Building a Keymap + +You should be able to build the keyboard keymap with a command in this format: + + make : + +### Conflicting layouts +When a keyboard supports multiple layout options, + + LAYOUTS = ortho_4x4 ortho_4x12 + +And a layout exists for both options, +``` +layouts/ ++ community/ +| + ortho_4x4/ +| | + / +| | | + ... +| + ortho_4x12/ +| | + / +| | | + ... +| + ... +``` + +The FORCE_LAYOUT argument can be used to specify which layout to build + + make : FORCE_LAYOUT=ortho_4x4 + make : FORCE_LAYOUT=ortho_4x12 + +## Tips for Making Layouts Keyboard-Agnostic + +### Includes + +Instead of using `#include "planck.h"`, you can use this line to include whatever `.h` (`.h` should not be included here) file that is being compiled: + + #include QMK_KEYBOARD_H + +If you want to keep some keyboard-specific code, you can use these variables to escape it with an `#ifdef` statement: + +* `KEYBOARD__` + +For example: + +```c +#ifdef KEYBOARD_planck + #ifdef KEYBOARD_planck_rev4 + planck_rev4_function(); + #endif +#endif +``` + +Note that the names are lowercase and match the folder/file names for the keyboard/revision exactly. + +### Keymaps + +In order to support both split and non-split keyboards with the same layout, you need to use the keyboard agnostic `LAYOUT_` macro in your keymap. For instance, in order for a Let's Split and Planck to share the same layout file, you need to use `LAYOUT_ortho_4x12` instead of `LAYOUT_planck_grid` or just `{}` for a C array. diff --git a/feature_leader_key.md b/feature_leader_key.md new file mode 100644 index 00000000000..0803a411c6c --- /dev/null +++ b/feature_leader_key.md @@ -0,0 +1,146 @@ +# The Leader Key: A New Kind of Modifier + +If you've ever used Vim, you know what a Leader key is. If not, you're about to discover a wonderful concept. :) Instead of hitting Alt+Shift+W for example (holding down three keys at the same time), what if you could hit a _sequence_ of keys instead? So you'd hit our special modifier (the Leader key), followed by W and then C (just a rapid succession of keys), and something would happen. + +That's what `KC_LEAD` does. Here's an example: + +1. Pick a key on your keyboard you want to use as the Leader key. Assign it the keycode `KC_LEAD`. This key would be dedicated just for this -- it's a single action key, can't be used for anything else. +2. Include the line `#define LEADER_TIMEOUT 300` in your `config.h`. This sets the timeout for the `KC_LEAD` key. Specifically, when you press the `KC_LEAD` key, you only have a certain amount of time to complete the Leader Key sequence. The `300` here sets that to 300ms, and you can increase this value to give you more time to hit the sequence. But any keys pressed during this timeout are intercepted and not sent, so you may want to keep this value low. + * By default, this timeout is how long after pressing `KC_LEAD` to complete your entire sequence. This may be very low for some people. So you may want to increase this timeout. Optionally, you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped. This allows you to maintain a low value here, but still be able to use the longer sequences. To enable this option, add `#define LEADER_PER_KEY_TIMING` to your `config.h`. +3. Within your `matrix_scan_user` function, add something like this: + +```c +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + leading = false; + leader_end(); + + SEQ_ONE_KEY(KC_F) { + // Anything you can do in a macro. + SEND_STRING("QMK is awesome."); + } + SEQ_TWO_KEYS(KC_D, KC_D) { + SEND_STRING(SS_LCTL("a") SS_LCTL("c")); + } + SEQ_THREE_KEYS(KC_D, KC_D, KC_S) { + SEND_STRING("https://start.duckduckgo.com\n"); + } + SEQ_TWO_KEYS(KC_A, KC_S) { + register_code(KC_LGUI); + register_code(KC_S); + unregister_code(KC_S); + unregister_code(KC_LGUI); + } + } +} +``` + +As you can see, you have a few function. You can use `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS`, `SEQ_THREE_KEYS` up to `SEQ_FIVE_KEYS` for longer sequences. + +Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously. + +## Adding Leader Key Support in the `rules.mk` + +To add support for Leader Key you simply need to add a single line to your keymap's `rules.mk`: + +```make +LEADER_ENABLE = yes +``` + +## Per Key Timing on Leader keys + +Rather than relying on an incredibly high timeout for long leader key strings or those of us without 200wpm typing skills, we can enable per key timing to ensure that each key pressed provides us with more time to finish our stroke. This is incredibly helpful with leader key emulation of tap dance (read: multiple taps of the same key like C, C, C). + +In order to enable this, place this in your `config.h`: +```c +#define LEADER_PER_KEY_TIMING +``` + +After this, it's recommended that you lower your `LEADER_TIMEOUT` to something less that 300ms. + +```c +#define LEADER_TIMEOUT 250 +``` + +Now, something like this won't seem impossible to do without a 1000MS leader key timeout: + +```c +SEQ_THREE_KEYS(KC_C, KC_C, KC_C) { + SEND_STRING("Per key timing is great!!!"); +} +``` + +## Strict Key Processing + +By default, the Leader Key feature will filter the keycode out of [`Mod-Tap`](mod_tap.md) and [`Layer Tap`](feature_layers.md#switching-and-toggling-layers) functions when checking for the Leader sequences. That means if you're using `LT(3, KC_A)`, it will pick this up as `KC_A` for the sequence, rather than `LT(3, KC_A)`, giving a more expected behavior for newer users. + +While, this may be fine for most, if you want to specify the whole keycode (eg, `LT(3, KC_A)` from the example above) in the sequence, you can enable this by added `#define LEADER_KEY_STRICT_KEY_PROCESSING` to your `config.h` file. This will then disable the filtering, and you'll need to specify the whole keycode. + +## Customization + +The Leader Key feature has some additional customization to how the Leader Key feature works. It has two functions that can be called at certain parts of the process. Namely `leader_start()` and `leader_end()`. + +The `leader_start()` function is called when you tap the `KC_LEAD` key, and the `leader_end()` function is called when either the leader sequence is completed, or the leader timeout is hit. + +You can add these functions to your code (`keymap.c` usually) to add feedback to the Leader sequences (such as beeping or playing music). + +```c +void leader_start(void) { + // sequence started +} + +void leader_end(void) { + // sequence ended (no success/failuer detection) +} +``` + +### Example + +This example will play the Mario "One Up" sound when you hit `KC_LEAD` to start the Leader Sequence, and will play "All Star" if it completes successfully or "Rick Roll" you if it fails. + +```c +bool did_leader_succeed; +#ifdef AUDIO_ENABLE +float leader_start[][2] = SONG(ONE_UP_SOUND ); +float leader_succeed[][2] = SONG(ALL_STAR); +float leader_fail[][2] = SONG(RICK_ROLL); +#endif +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + did_leader_succeed = leading = false; + + SEQ_ONE_KEY(KC_E) { + // Anything you can do in a macro. + SEND_STRING(SS_LCTL(SS_LSFT("t"))); + did_leader_succeed = true; + } else + SEQ_TWO_KEYS(KC_E, KC_D) { + SEND_STRING(SS_LGUI("r") "cmd\n" SS_LCTL("c")); + did_leader_succeed = true; + } + leader_end(); + } +} + +void leader_start(void) { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_start); +#endif +} + +void leader_end(void) { + if (did_leader_succeed) { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_succeed); +#endif + } else { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_fail); +#endif + } +} +``` diff --git a/feature_led_indicators.md b/feature_led_indicators.md new file mode 100644 index 00000000000..10e095ab155 --- /dev/null +++ b/feature_led_indicators.md @@ -0,0 +1,116 @@ +# LED Indicators + +QMK provides methods to read 5 of the LEDs defined in the HID spec: + +* Num Lock +* Caps Lock +* Scroll Lock +* Compose +* Kana + +There are three ways to get the lock LED state: +* by specifying configuration options within `config.h` +* by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or +* by calling `led_t host_keyboard_led_state()` + +!> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called. + +Two more deprecated functions exist that provide the LED state as a `uint8_t`: + +* `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)` +* `uint8_t host_keyboard_leds()` + +## Configuration Options + +To configure the indicators, `#define` these in your `config.h`: + +|Define |Default |Description | +|---------------------|-------------|-------------------------------------------| +|`LED_NUM_LOCK_PIN` |*Not defined*|The pin that controls the `Num Lock` LED | +|`LED_CAPS_LOCK_PIN` |*Not defined*|The pin that controls the `Caps Lock` LED | +|`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| +|`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | +|`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | +|`LED_PIN_ON_STATE` |`1` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| + +Unless you are designing your own keyboard, you generally should not need to change the above config options. + +## `led_update_*()` + +When the configuration options do not provide enough flexibility, the API hooks provided allow custom control of the LED behavior. These functions will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter. + +By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and +return `false` when you would prefer not to run the code in `led_update_kb()`. + +Some examples include: + + - overriding the LEDs to use them for something else like layer indication + - return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior. + - play a sound when an LED turns on or off. + - return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior. + +?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead. + +### Example `led_update_kb()` Implementation + +```c +bool led_update_kb(led_t led_state) { + bool res = led_update_user(led_state); + if(res) { + // writePin sets the pin high for 1 and low for 0. + // In this example the pins are inverted, setting + // it low/0 turns it on, and high/1 turns the LED off. + // This behavior depends on whether the LED is between the pin + // and VCC or the pin and GND. + writePin(B0, !led_state.num_lock); + writePin(B1, !led_state.caps_lock); + writePin(B2, !led_state.scroll_lock); + writePin(B3, !led_state.compose); + writePin(B4, !led_state.kana); + } + return res; +} +``` + +### Example `led_update_user()` Implementation + +This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state. + +```c +#ifdef AUDIO_ENABLE + float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); + float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); +#endif + +bool led_update_user(led_t led_state) { + #ifdef AUDIO_ENABLE + static uint8_t caps_state = 0; + if (caps_state != led_state.caps_lock) { + led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); + caps_state = led_state.caps_lock; + } + #endif + return true; +} +``` + +### `led_update_*` Function Documentation + +* Keyboard/Revision: `bool led_update_kb(led_t led_state)` +* Keymap: `bool led_update_user(led_t led_state)` + +## `host_keyboard_led_state()` + +Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code). + +## Setting Physical LED State + +Some keyboard implementations provide convenience methods for setting the state of the physical LEDs. + +### Ergodox Boards + +The Ergodox implementations provide `ergodox_right_led_1`/`2`/`3_on`/`off()` to turn individual LEDs on or off, as well as `ergodox_right_led_on`/`off(uint8_t led)` to turn them on or off by their index. + +In addition, it is possible to specify the brightness level of all LEDs with `ergodox_led_all_set(uint8_t n)`; of individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`; or by index with `ergodox_right_led_set(uint8_t led, uint8_t n)`. + +Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). diff --git a/feature_led_matrix.md b/feature_led_matrix.md new file mode 100644 index 00000000000..372407b90c2 --- /dev/null +++ b/feature_led_matrix.md @@ -0,0 +1,90 @@ +# LED Matrix Lighting + +This feature allows you to use LED matrices driven by external drivers. It hooks into the backlight system so you can use the same keycodes as backlighting to control it. + +If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix.md) instead. + +## Driver configuration + +### IS31FL3731 + +There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: + + LED_MATRIX_ENABLE = IS31FL3731 + +You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: + +| Variable | Description | Default | +|----------|-------------|---------| +| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages | 100 | +| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | +| `LED_DRIVER_COUNT` | (Required) How many LED driver IC's are present | | +| `LED_DRIVER_LED_COUNT` | (Required) How many LED lights are present across all drivers | | +| `LED_DRIVER_ADDR_1` | (Required) Address for the first LED driver | | +| `LED_DRIVER_ADDR_2` | (Optional) Address for the second LED driver | | +| `LED_DRIVER_ADDR_3` | (Optional) Address for the third LED driver | | +| `LED_DRIVER_ADDR_4` | (Optional) Address for the fourth LED driver | | + +Here is an example using 2 drivers. + + // This is a 7-bit address, that gets left-shifted and bit 0 + // set to 0 for write, 1 for read (as per I2C protocol) + // The address will vary depending on your wiring: + // 0b1110100 AD <-> GND + // 0b1110111 AD <-> VCC + // 0b1110101 AD <-> SCL + // 0b1110110 AD <-> SDA + #define LED_DRIVER_ADDR_1 0b1110100 + #define LED_DRIVER_ADDR_2 0b1110110 + + #define LED_DRIVER_COUNT 2 + #define LED_DRIVER_1_LED_COUNT 25 + #define LED_DRIVER_2_LED_COUNT 24 + #define LED_DRIVER_LED_COUNT LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL + +Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations. + +Define these arrays listing all the LEDs in your `.c`: + + const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + /* Refer to IS31 manual for these locations + * driver + * | LED address + * | | */ + {0, C3_3}, + .... + } + +Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ). + +## Keycodes + +All LED matrix keycodes are currently shared with the [backlight system](feature_backlight.md). + +## LED Matrix Effects + +Currently no LED matrix effects have been created. + +## Custom layer effects + +Custom layer effects can be done by defining this in your `.c`: + + void led_matrix_indicators_kb(void) { + led_matrix_set_index_value(index, value); + } + +A similar function works in the keymap as `led_matrix_indicators_user`. + +## Suspended state + +To use the suspend feature, add this to your `.c`: + + void suspend_power_down_kb(void) + { + led_matrix_set_suspend_state(true); + } + + void suspend_wakeup_init_kb(void) + { + led_matrix_set_suspend_state(false); + } diff --git a/feature_macros.md b/feature_macros.md new file mode 100644 index 00000000000..acd40d1bf34 --- /dev/null +++ b/feature_macros.md @@ -0,0 +1,397 @@ +# Macros + +Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code. + +!> **Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor. + +## The New Way: `SEND_STRING()` & `process_record_user` + +Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`). + +Here is an example `keymap.c` for a two-key keyboard: + +```c +enum custom_keycodes { + QMKBEST = SAFE_RANGE, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QMKBEST: + if (record->event.pressed) { + // when keycode QMKBEST is pressed + SEND_STRING("QMK is the best thing ever!"); + } else { + // when keycode QMKBEST is released + } + break; + } + return true; +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = { + {QMKBEST, KC_ESC}, + // ... + }, +}; +``` + +What happens here is this: +We first define a new custom keycode in the range not occupied by any other keycodes. +Then we use the `process_record_user` function, which is called whenever a key is pressed or released, to check if our custom keycode has been activated. +If yes, we send the string `"QMK is the best thing ever!"` to the computer via the `SEND_STRING` macro (this is a C preprocessor macro, not to be confused with QMK macros). +We return `true` to indicate to the caller that the key press we just processed should continue to be processed as normal (as we didn't replace or alter the functionality). +Finally, we define the keymap so that the first button activates our macro and the second button is just an escape button. + +You might want to add more than one macro. +You can do that by adding another keycode and adding another case to the switch statement, like so: + +```c +enum custom_keycodes { + QMKBEST = SAFE_RANGE, + QMKURL, + MY_OTHER_MACRO, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QMKBEST: + if (record->event.pressed) { + // when keycode QMKBEST is pressed + SEND_STRING("QMK is the best thing ever!"); + } else { + // when keycode QMKBEST is released + } + break; + + case QMKURL: + if (record->event.pressed) { + // when keycode QMKURL is pressed + SEND_STRING("https://qmk.fm/\n"); + } else { + // when keycode QMKURL is released + } + break; + + case MY_OTHER_MACRO: + if (record->event.pressed) { + SEND_STRING(SS_LCTL("ac")); // selects all and copies + } + break; + } + return true; +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = { + {MY_CUSTOM_MACRO, MY_OTHER_MACRO}, + // ... + }, +}; +``` + +### Advanced Macros + +In addition to the `process_record_user()` function, is the `post_process_record_user()` function. This runs after `process_record` and can be used to do things after a keystroke has been sent. This is useful if you want to have a key pressed before and released after a normal key, for instance. + +In this example, we modify most normal keypresses so that `F22` is pressed before the keystroke is normally sent, and release it __only after__ it's been released. + +```c +static uint8_t f22_tracker; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_A ... KC_F21: //notice how it skips over F22 + case KC_F23 ... KC_EXSEL: //exsel is the last one before the modifier keys + if (record->event.pressed) { + register_code(KC_F22); //this means to send F22 down + f22_tracker++; + register_code(keycode); + return false; + } + break; + } + return true; +} + +void post_process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_A ... KC_F21: //notice how it skips over F22 + case KC_F23 ... KC_EXSEL: //exsel is the last one before the modifier keys + if (!record->event.pressed) { + f22_tracker--; + if (!f22_tracker) { + unregister_code(KC_F22); //this means to send F22 up + } + } + break; + } +} +``` + + +### TAP, DOWN and UP + +You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`. +You can send arbitrary keycodes by wrapping them in: + +* `SS_TAP()` presses and releases a key. +* `SS_DOWN()` presses (but does not release) a key. +* `SS_UP()` releases a key. + +For example: + + SEND_STRING(SS_TAP(X_HOME)); + +Would tap `KC_HOME` - note how the prefix is now `X_`, and not `KC_`. You can also combine this with other strings, like this: + + SEND_STRING("VE"SS_TAP(X_HOME)"LO"); + +Which would send "VE" followed by a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline). + +Delays can be also added to the string: + +* `SS_DELAY(msecs)` will delay for the specified number of milliseconds. + +For example: + + SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO"); + +Which would send "VE" followed by a 1-second delay, then a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline, but delayed in the middle). + +There's also a couple of mod shortcuts you can use: + +* `SS_LCTL(string)` +* `SS_LSFT(string)` +* `SS_LALT(string)` or `SS_LOPT(string)` +* `SS_LGUI(string)`, `SS_LCMD(string)` or `SS_LWIN(string)` +* `SS_RCTL(string)` +* `SS_RSFT(string)` +* `SS_RALT(string)`, `SS_ROPT(string)` or `SS_ALGR(string)` +* `SS_RGUI(string)`, `SS_RCMD(string)` or `SS_RWIN(string)` + +These press the respective modifier, send the supplied string and then release the modifier. +They can be used like this: + + SEND_STRING(SS_LCTL("a")); + +Which would send Left Control+`a` (Left Control down, `a`, Left Control up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes. + +### Alternative Keymaps + +By default, it assumes a US keymap with a QWERTY layout; if you want to change that (e.g. if your OS uses software Colemak), include this somewhere in your keymap: + + #include + +### Strings in Memory + +If for some reason you're manipulating strings and need to print out something you just generated (instead of being a literal, constant string), you can use `send_string()`, like this: + +```c +char my_str[4] = "ok."; +send_string(my_str); +``` + +The shortcuts defined above won't work with `send_string()`, but you can separate things out to different lines if needed: + +```c +char my_str[4] = "ok."; +SEND_STRING("I said: "); +send_string(my_str); +SEND_STRING(".."SS_TAP(X_END)); +``` + + +## Advanced Macro Functions + +There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple. + +?> You can also use the functions described in [Useful function](ref_functions.md) for additional functionality. For example `reset_keyboard()` allows you to reset the keyboard as part of a macro. + +### `record->event.pressed` + +This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is + +```c + if (record->event.pressed) { + // on keydown + } else { + // on keyup + } +``` + +### `register_code();` + +This sends the `` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`. + +### `unregister_code();` + +Parallel to `register_code` function, this sends the `` keyup event to the computer. If you don't use this, the key will be held down until it's sent. + +### `tap_code();` + +This will send `register_code()` and then `unregister_code()`. This is useful if you want to send both the press and release events ("tap" the key, rather than hold it). + +If you're having issues with taps (un)registering, you can add a delay between the register and unregister events by setting `#define TAP_CODE_DELAY 100` in your `config.h` file. The value is in milliseconds. + +### `register_code16();`, `unregister_code16();` and `tap_code16();` + +These functions work similar to their regular counterparts, but allow you to use modded keycodes (with Shift, Alt, Control, and/or GUI applied to them). + +Eg, you could use `register_code16(S(KC_5));` instead of registering the mod, then registering the keycode. + +### `clear_keyboard();` + +This will clear all mods and keys currently pressed. + +### `clear_mods();` + +This will clear all mods currently pressed. + +### `clear_keyboard_but_mods();` + +This will clear all keys besides the mods currently pressed. + +## Advanced Example: + +### Super ALT↯TAB + +This macro will register `KC_LALT` and tap `KC_TAB`, then wait for 1000ms. If the key is tapped again, it will send another `KC_TAB`; if there is no tap, `KC_LALT` will be unregistered, thus allowing you to cycle through windows. + +```c +bool is_alt_tab_active = false; # ADD this near the begining of keymap.c +uint16_t alt_tab_timer = 0; # we will be using them soon. + +enum custom_keycodes { # Make sure have the awesome keycode ready + ALT_TAB = SAFE_RANGE, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { # This will do most of the grunt work with the keycodes. + case ALT_TAB: + if (record->event.pressed) { + if (!is_alt_tab_active) { + is_alt_tab_active = true; + register_code(KC_LALT); + } + alt_tab_timer = timer_read(); + register_code(KC_TAB); + } else { + unregister_code(KC_TAB); + } + break; + } + return true; +} + +void matrix_scan_user(void) { # The very important timer. + if (is_alt_tab_active) { + if (timer_elapsed(alt_tab_timer) > 1000) { + unregister_code(KC_LALT); + is_alt_tab_active = false; + } + } +} +``` + +--- + +## **(DEPRECATED)** The Old Way: `MACRO()` & `action_get_macro` + +!> This is inherited from TMK, and hasn't been updated - it's recommended that you use `SEND_STRING` and `process_record_user` instead. + +By default QMK assumes you don't have any macros. To define your macros you create an `action_get_macro()` function. For example: + +```c +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + if (record->event.pressed) { + switch(id) { + case 0: + return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); + case 1: + return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); + } + } + return MACRO_NONE; +}; +``` + +This defines two macros which will be run when the key they are assigned to is pressed. If instead you'd like them to run when the key is released you can change the if statement: + + if (!record->event.pressed) { + +### Macro Commands + +A macro can include the following commands: + +* I() change interval of stroke in milliseconds. +* D() press key. +* U() release key. +* T() type key(press and release). +* W() wait (milliseconds). +* END end mark. + +### Mapping a Macro to a Key + +Use the `M()` function within your keymap to call a macro. For example, here is the keymap for a 2-key keyboard: + +```c +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + M(0), M(1) + ), +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + if (record->event.pressed) { + switch(id) { + case 0: + return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); + case 1: + return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); + } + } + return MACRO_NONE; +}; +``` + +When you press the key on the left it will type "Hi!" and when you press the key on the right it will type "Bye!". + +### Naming Your Macros + +If you have a bunch of macros you want to refer to from your keymap while keeping the keymap easily readable you can name them using `#define` at the top of your file. + +```c +#define M_HI M(0) +#define M_BYE M(1) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + M_HI, M_BYE + ), +}; +``` + + +## Advanced Example: + +### Single-Key Copy/Paste + +This example defines a macro which sends `Ctrl-C` when pressed down, and `Ctrl-V` when released. + +```c +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + switch(id) { + case 0: { + if (record->event.pressed) { + return MACRO( D(LCTL), T(C), U(LCTL), END ); + } else { + return MACRO( D(LCTL), T(V), U(LCTL), END ); + } + break; + } + } + return MACRO_NONE; +}; +``` diff --git a/feature_mouse_keys.md b/feature_mouse_keys.md new file mode 100644 index 00000000000..a6b46bc151f --- /dev/null +++ b/feature_mouse_keys.md @@ -0,0 +1,142 @@ +# Mouse keys + +Mouse keys is a feature that allows you to emulate a mouse using your keyboard. You can move the pointer at different speeds, press 5 buttons and scroll in 8 directions. + +## Adding mouse keys to your keyboard + +To use mouse keys, you must at least enable mouse keys support and map mouse actions to keys on your keyboard. + +### Enabling mouse keys + +To enable mouse keys, add the following line to your keymap’s `rules.mk`: + +```c +MOUSEKEY_ENABLE = yes +``` + +### Mapping mouse actions + +In your keymap you can use the following keycodes to map key presses to mouse actions: + +|Key |Aliases |Description | +|----------------|---------|-----------------| +|`KC_MS_UP` |`KC_MS_U`|Move cursor up | +|`KC_MS_DOWN` |`KC_MS_D`|Move cursor down | +|`KC_MS_LEFT` |`KC_MS_L`|Move cursor left | +|`KC_MS_RIGHT` |`KC_MS_R`|Move cursor right| +|`KC_MS_BTN1` |`KC_BTN1`|Press button 1 | +|`KC_MS_BTN2` |`KC_BTN2`|Press button 2 | +|`KC_MS_BTN3` |`KC_BTN3`|Press button 3 | +|`KC_MS_BTN4` |`KC_BTN4`|Press button 4 | +|`KC_MS_BTN5` |`KC_BTN5`|Press button 5 | +|`KC_MS_WH_UP` |`KC_WH_U`|Move wheel up | +|`KC_MS_WH_DOWN` |`KC_WH_D`|Move wheel down | +|`KC_MS_WH_LEFT` |`KC_WH_L`|Move wheel left | +|`KC_MS_WH_RIGHT`|`KC_WH_R`|Move wheel right | +|`KC_MS_ACCEL0` |`KC_ACL0`|Set speed to 0 | +|`KC_MS_ACCEL1` |`KC_ACL1`|Set speed to 1 | +|`KC_MS_ACCEL2` |`KC_ACL2`|Set speed to 2 | + +## Configuring mouse keys + +Mouse keys supports three different modes to move the cursor: + +* **Accelerated (default):** Holding movement keys accelerates the cursor until it reaches its maximum speed. +* **Constant:** Holding movement keys moves the cursor at constant speeds. +* **Combined:** Holding movement keys accelerates the cursor until it reaches its maximum speed, but holding acceleration and movement keys simultaneously moves the cursor at constant speeds. + +The same principle applies to scrolling. + +Configuration options that are times, intervals or delays are given in milliseconds. Scroll speed is given as multiples of the default scroll step. For example, a scroll speed of 8 means that each scroll action covers 8 times the length of the default scroll step as defined by your operating system or application. + +### Accelerated mode + +This is the default mode. You can adjust the cursor and scrolling acceleration using the following settings in your keymap’s `config.h` file: + +|Define |Default|Description | +|----------------------------|-------|---------------------------------------------------------| +|`MOUSEKEY_DELAY` |300 |Delay between pressing a movement key and cursor movement| +|`MOUSEKEY_INTERVAL` |50 |Time between cursor movements | +|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops | +|`MOUSEKEY_TIME_TO_MAX` |20 |Time until maximum cursor speed is reached | +|`MOUSEKEY_WHEEL_DELAY` |300 |Delay between pressing a wheel key and wheel movement | +|`MOUSEKEY_WHEEL_INTERVAL` |100 |Time between wheel movements | +|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action | +|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached | + +Tips: + +* Setting `MOUSEKEY_DELAY` too low makes the cursor unresponsive. Setting it too high makes small movements difficult. +* For smoother cursor movements, lower the value of `MOUSEKEY_INTERVAL`. If the refresh rate of your display is 60Hz, you could set it to `16` (1/60). As this raises the cursor speed significantly, you may want to lower `MOUSEKEY_MAX_SPEED`. +* Setting `MOUSEKEY_TIME_TO_MAX` or `MOUSEKEY_WHEEL_TIME_TO_MAX` to `0` will disable acceleration for the cursor or scrolling respectively. This way you can make one of them constant while keeping the other accelerated, which is not possible in constant speed mode. +* Setting `MOUSEKEY_WHEEL_INTERVAL` too low will make scrolling too fast. Setting it too high will make scrolling too slow when the wheel key is held down. + +Cursor acceleration uses the same algorithm as the X Window System MouseKeysAccel feature. You can read more about it [on Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys). + +### Constant mode + +In this mode you can define multiple different speeds for both the cursor and the mouse wheel. There is no acceleration. `KC_ACL0`, `KC_ACL1` and `KC_ACL2` change the cursor and scroll speed to their respective setting. + +You can choose whether speed selection is momentary or tap-to-select: + +* **Momentary:** The chosen speed is only active while you hold the respective key. When the key is raised, mouse keys returns to the unmodified speed. +* **Tap-to-select:** The chosen speed is activated when you press the respective key and remains active even after the key has been raised. The default speed is that of `KC_ACL1`. There is no unmodified speed. + +The default speeds from slowest to fastest are as follows: + +* **Momentary:** `KC_ACL0` < `KC_ACL1` < *unmodified* < `KC_ACL2` +* **Tap-to-select:** `KC_ACL0` < `KC_ACL1` < `KC_ACL2` + +To use constant speed mode, you must at least define `MK_3_SPEED` in your keymap’s `config.h` file: + +```c +#define MK_3_SPEED +``` + +To enable momentary mode, also define `MK_MOMENTARY_ACCEL`: + +```c +#define MK_MOMENTARY_ACCEL +``` + +Use the following settings if you want to adjust cursor movement or scrolling: + +|Define |Default |Description | +|---------------------|-------------|-------------------------------------------| +|`MK_3_SPEED` |*Not defined*|Enable constant cursor speeds | +|`MK_MOMENTARY_ACCEL` |*Not defined*|Enable momentary speed selection | +|`MK_C_OFFSET_UNMOD` |16 |Cursor offset per movement (unmodified) | +|`MK_C_INTERVAL_UNMOD`|16 |Time between cursor movements (unmodified) | +|`MK_C_OFFSET_0` |1 |Cursor offset per movement (`KC_ACL0`) | +|`MK_C_INTERVAL_0` |32 |Time between cursor movements (`KC_ACL0`) | +|`MK_C_OFFSET_1` |4 |Cursor offset per movement (`KC_ACL1`) | +|`MK_C_INTERVAL_1` |16 |Time between cursor movements (`KC_ACL1`) | +|`MK_C_OFFSET_2` |32 |Cursor offset per movement (`KC_ACL2`) | +|`MK_C_INTERVAL_2` |16 |Time between cursor movements (`KC_ACL2`) | +|`MK_W_OFFSET_UNMOD` |1 |Scroll steps per scroll action (unmodified)| +|`MK_W_INTERVAL_UNMOD`|40 |Time between scroll steps (unmodified) | +|`MK_W_OFFSET_0` |1 |Scroll steps per scroll action (`KC_ACL0`) | +|`MK_W_INTERVAL_0` |360 |Time between scroll steps (`KC_ACL0`) | +|`MK_W_OFFSET_1` |1 |Scroll steps per scroll action (`KC_ACL1`) | +|`MK_W_INTERVAL_1` |120 |Time between scroll steps (`KC_ACL1`) | +|`MK_W_OFFSET_2` |1 |Scroll steps per scroll action (`KC_ACL2`) | +|`MK_W_INTERVAL_2` |20 |Time between scroll steps (`KC_ACL2`) | + +### Combined mode + +This mode functions like **Accelerated** mode, however, you can hold `KC_ACL0`, `KC_ACL1` and `KC_ACL2` +to momentarily (while held) set the cursor and scroll speeds to constant speeds. When no acceleration +keys are held, this mode is identical to **Accelerated** mode, and can be modified using all of the +relevant settings. + +* **KC_ACL0:** This acceleration sets your cursor to the slowest possible speed. This is useful for very +small and detailed movements of the cursor. +* **KC_ACL1:** This acceleration sets your cursor to half the maximum (user defined) speed. +* **KC_ACL2:** This acceleration sets your cursor to the maximum (computer defined) speed. This is +useful for moving the cursor large distances without much accuracy. + +To use constant speed mode, you must at least define `MK_COMBINED` in your keymap’s `config.h` file: + +```c +#define MK_COMBINED +``` diff --git a/feature_oled_driver.md b/feature_oled_driver.md new file mode 100644 index 00000000000..9f0ef1664b1 --- /dev/null +++ b/feature_oled_driver.md @@ -0,0 +1,377 @@ +# OLED Driver + +## Supported Hardware + +OLED modules using SSD1306 or SH1106 driver ICs, communicating over I2C. +Tested combinations: + +|IC |Size |Platform|Notes | +|---------|------|--------|------------------------| +|SSD1306 |128x32|AVR |Primary support | +|SSD1306 |128x64|AVR |Verified working | +|SSD1306 |128x32|Arm | | +|SH1106 |128x64|AVR |No rotation or scrolling| + +Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested. + +!> Warning: This OLED driver currently uses the new i2c_master driver from Split Common code. If your split keyboard uses I2C to communicate between sides, this driver could cause an address conflict (serial is fine). Please contact your keyboard vendor and ask them to migrate to the latest Split Common code to fix this. In addition, the display timeout system to reduce OLED burn-in also uses Split Common to detect keypresses, so you will need to implement custom timeout logic for non-Split Common keyboards. + +## Usage + +To enable the OLED feature, there are three steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`: + +```make +OLED_DRIVER_ENABLE = yes +``` + +Then in your `keymap.c` file, implement the OLED task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`: + +```c +#ifdef OLED_DRIVER_ENABLE +void oled_task_user(void) { + // Host Keyboard Layer Status + oled_write_P(PSTR("Layer: "), false); + + switch (get_highest_layer(layer_state)) { + case _QWERTY: + oled_write_P(PSTR("Default\n"), false); + break; + case _FN: + oled_write_P(PSTR("FN\n"), false); + break; + case _ADJ: + oled_write_P(PSTR("ADJ\n"), false); + break; + default: + // Or use the write_ln shortcut over adding '\n' to the end of your string + oled_write_ln_P(PSTR("Undefined"), false); + } + + // Host Keyboard LED Status + led_t led_state = host_keyboard_led_state(); + oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); + oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false); + oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false); +} +#endif +``` + +## Logo Example + +In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the OLED screen, use the following code example: + +```c +static void render_logo(void) { + static const char PROGMEM qmk_logo[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 + }; + + oled_write_P(qmk_logo, false); +} +``` + +## Buffer Read Example +For some purposes, you may need to read the current state of the OLED display +buffer. The `oled_read_raw` function can be used to safely read bytes from the +buffer. + +In this example, calling `fade_display` in the `oled_task_user` function will +slowly fade away whatever is on the screen by turning random pixels black over +time. +```c +//Setup some mask which can be or'd with bytes to turn off pixels +const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254}; + +static void fade_display(void) { + //Define the reader structure + oled_buffer_reader_t reader; + uint8_t buff_char; + if (random() % 30 == 0) { + srand(timer_read()); + // Fetch a pointer for the buffer byte at index 0. The return structure + // will have the pointer and the number of bytes remaining from this + // index position if we want to perform a sequential read by + // incrementing the buffer pointer + reader = oled_read_raw(0); + //Loop over the remaining buffer and erase pixels as we go + for (uint16_t i = 0; i < reader.remaining_element_count; i++) { + //Get the actual byte in the buffer by dereferencing the pointer + buff_char = *reader.current_element; + if (buff_char != 0) { + oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i); + } + //increment the pointer to fetch a new byte during the next loop + reader.current_element++; + } + } +} +``` + +## Other Examples + +In split keyboards, it is very common to have two OLED displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g: + +```c +#ifdef OLED_DRIVER_ENABLE +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (!is_keyboard_master()) { + return OLED_ROTATION_180; // flips the display 180 degrees if offhand + } + + return rotation; +} + +void oled_task_user(void) { + if (is_keyboard_master()) { + render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc) + } else { + render_logo(); // Renders a static logo + oled_scroll_left(); // Turns on scrolling + } +} +#endif +``` + +## Basic Configuration + +|Define |Default |Description | +|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------| +|`OLED_DISPLAY_ADDRESS` |`0x3C` |The i2c address of the OLED Display | +|`OLED_FONT_H` |`"glcdfont.c"` |The font code file to use for custom fonts | +|`OLED_FONT_START` |`0` |The starting character index for custom fonts | +|`OLED_FONT_END` |`223` |The ending character index for custom fonts | +|`OLED_FONT_WIDTH` |`6` |The font width | +|`OLED_FONT_HEIGHT` |`8` |The font height (untested) | +|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of keyboard inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. | +|`OLED_SCROLL_TIMEOUT` |`0` |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. | +|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. | +|`OLED_IC` |`OLED_IC_SSD1306`|Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller. | +|`OLED_COLUMN_OFFSET` |`0` |(SH1106 only.) Shift output to the right this many pixels.
Useful for 128x64 displays centered on a 132x64 SH1106 IC.| +|`OLED_BRIGHTNESS` |`255` |The default brightness level of the OLED, from 0 to 255. | + + ## 128x64 & Custom sized OLED Displays + + The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind. We have added a define, `OLED_DISPLAY_128X64`, to switch all the values to be used in a 128x64 display, as well as added a custom define, `OLED_DISPLAY_CUSTOM`, that allows you to provide the necessary values to the driver. + +|Define |Default |Description | +|---------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------| +|`OLED_DISPLAY_128X64`|*Not defined* |Changes the display defines for use with 128x64 displays. | +|`OLED_DISPLAY_CUSTOM`|*Not defined* |Changes the display defines for use with custom displays.
Requires user to implement the below defines. | +|`OLED_DISPLAY_WIDTH` |`128` |The width of the OLED display. | +|`OLED_DISPLAY_HEIGHT`|`32` |The height of the OLED display. | +|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.
`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. | +|`OLED_BLOCK_TYPE` |`uint16_t` |The unsigned integer type to use for dirty rendering. | +|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.
`(sizeof(OLED_BLOCK_TYPE) * 8)`. | +|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering
`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. | +|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.
Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.| +|`OLED_SOURCE_MAP` |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering. | +|`OLED_TARGET_MAP` |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering. | + + +### 90 Degree Rotation - Technical Mumbo Jumbo + +!> Rotation is unsupported on the SH1106. + +```c +// OLED Rotation enum values are flags +typedef enum { + OLED_ROTATION_0 = 0, + OLED_ROTATION_90 = 1, + OLED_ROTATION_180 = 2, + OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180 +} oled_rotation_t; +``` + +OLED displays driven by SSD1306 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms. + +90 degree rotation is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the display height, width, and block size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g: + +| | | | | | | +|---|---|---|---|---|---| +| 0 | 1 | | | | | +| 2 | 3 | | | | | +| 4 | 5 | | | | | +| 6 | 7 | | | | | + +However the local buffer is stored as if it was Height x Width display instead of Width x Height, e.g: + +| | | | | | | +|---|---|---|---|---|---| +| 3 | 7 | | | | | +| 2 | 6 | | | | | +| 1 | 5 | | | | | +| 0 | 4 | | | | | + +So those precalculated arrays just index the memory offsets in the order in which each one iterates its data. + +## OLED API + +```c +// OLED rotation enum values are flags +typedef enum { + OLED_ROTATION_0 = 0, + OLED_ROTATION_90 = 1, + OLED_ROTATION_180 = 2, + OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180 +} oled_rotation_t; + +// Initialize the OLED display, rotating the rendered output based on the define passed in. +// Returns true if the OLED was initialized successfully +bool oled_init(oled_rotation_t rotation); + +// Called at the start of oled_init, weak function overridable by the user +// rotation - the value passed into oled_init +// Return new oled_rotation_t if you want to override default rotation +oled_rotation_t oled_init_user(oled_rotation_t rotation); + +// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering +void oled_clear(void); + +// Renders the dirty chunks of the buffer to OLED display +void oled_render(void); + +// Moves cursor to character position indicated by column and line, wraps if out of bounds +// Max column denoted by 'oled_max_chars()' and max lines by 'oled_max_lines()' functions +void oled_set_cursor(uint8_t col, uint8_t line); + +// Advances the cursor to the next page, writing ' ' if true +// Wraps to the begining when out of bounds +void oled_advance_page(bool clearPageRemainder); + +// Moves the cursor forward 1 character length +// Advance page if there is not enough room for the next character +// Wraps to the begining when out of bounds +void oled_advance_char(void); + +// Writes a single character to the buffer at current cursor position +// Advances the cursor while writing, inverts the pixels if true +// Main handler that writes character data to the display buffer +void oled_write_char(const char data, bool invert); + +// Writes a string to the buffer at current cursor position +// Advances the cursor while writing, inverts the pixels if true +void oled_write(const char *data, bool invert); + +// Writes a string to the buffer at current cursor position +// Advances the cursor while writing, inverts the pixels if true +// Advances the cursor to the next page, wiring ' ' to the remainder of the current page +void oled_write_ln(const char *data, bool invert); + +// Pans the buffer to the right (or left by passing true) by moving contents of the buffer +// Useful for moving the screen in preparation for new drawing +// oled_scroll_left or oled_scroll_right should be preferred for all cases of moving a static +// image such as a logo or to avoid burn-in as it's much, much less cpu intensive +void oled_pan(bool left); + +// Writes a PROGMEM string to the buffer at current cursor position +// Advances the cursor while writing, inverts the pixels if true +// Remapped to call 'void oled_write(const char *data, bool invert);' on ARM +void oled_write_P(const char *data, bool invert); + +// Writes a PROGMEM string to the buffer at current cursor position +// Advances the cursor while writing, inverts the pixels if true +// Advances the cursor to the next page, wiring ' ' to the remainder of the current page +// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM +void oled_write_ln_P(const char *data, bool invert); + +// Returns a pointer to the requested start index in the buffer plus remaining +// buffer length as struct +oled_buffer_reader_t oled_read_raw(uint16_t start_index); + +// Writes a string to the buffer at current cursor position +void oled_write_raw(const char *data, uint16_t size); + +// Writes a single byte into the buffer at the specified index +void oled_write_raw_byte(const char data, uint16_t index); + +// Writes a PROGMEM string to the buffer at current cursor position +void oled_write_raw_P(const char *data, uint16_t size); + +// Sets a specific pixel on or off +// Coordinates start at top-left and go right and down for positive x and y +void oled_write_pixel(uint8_t x, uint8_t y, bool on); + +// Can be used to manually turn on the screen if it is off +// Returns true if the screen was on or turns on +bool oled_on(void); + +// Can be used to manually turn off the screen if it is on +// Returns true if the screen was off or turns off +bool oled_off(void); + +// Returns true if the oled is currently on, false if it is +// not +bool is_oled_on(void); + +// Sets the brightness level of the display +uint8_t oled_set_brightness(uint8_t level); + +// Gets the current brightness level of the display +uint8_t oled_get_brightness(void); + +// Basically it's oled_render, but with timeout management and oled_task_user calling! +void oled_task(void); + +// Called at the start of oled_task, weak function overridable by the user +void oled_task_user(void); + +// Set the specific 8 lines rows of the screen to scroll. +// 0 is the default for start, and 7 for end, which is the entire +// height of the screen. For 128x32 screens, rows 4-7 are not used. +void oled_scroll_set_area(uint8_t start_line, uint8_t end_line); + +// Sets scroll speed, 0-7, fastest to slowest. Default is three. +// Does not take effect until scrolling is either started or restarted +// the ssd1306 supports 8 speeds with the delay +// listed below betwen each frame of the scrolling effect +// 0=2, 1=3, 2=4, 3=5, 4=25, 5=64, 6=128, 7=256 +void oled_scroll_set_speed(uint8_t speed); + +// Begin scrolling the entire display right +// Returns true if the screen was scrolling or starts scrolling +// NOTE: display contents cannot be changed while scrolling +bool oled_scroll_right(void); + +// Begin scrolling the entire display left +// Returns true if the screen was scrolling or starts scrolling +// NOTE: display contents cannot be changed while scrolling +bool oled_scroll_left(void); + +// Turns off display scrolling +// Returns true if the screen was not scrolling or stops scrolling +bool oled_scroll_off(void); + +// Returns the maximum number of characters that will fit on a line +uint8_t oled_max_chars(void); + +// Returns the maximum number of lines that will fit on the OLED +uint8_t oled_max_lines(void); +``` + +!> Scrolling and rotation are unsupported on the SH1106. + +## SSD1306.h Driver Conversion Guide + +|Old API |Recommended New API | +|-------------------------|---------------------------------| +|`struct CharacterMatrix` |*removed - delete all references*| +|`iota_gfx_init` |`oled_init` | +|`iota_gfx_on` |`oled_on` | +|`iota_gfx_off` |`oled_off` | +|`iota_gfx_flush` |`oled_render` | +|`iota_gfx_write_char` |`oled_write_char` | +|`iota_gfx_write` |`oled_write` | +|`iota_gfx_write_P` |`oled_write_P` | +|`iota_gfx_clear_screen` |`oled_clear` | +|`matrix_clear` |*removed - delete all references*| +|`matrix_write_char_inner`|`oled_write_char` | +|`matrix_write_char` |`oled_write_char` | +|`matrix_write` |`oled_write` | +|`matrix_write_ln` |`oled_write_ln` | +|`matrix_write_P` |`oled_write_P` | +|`matrix_write_ln_P` |`oled_write_ln_P` | +|`matrix_render` |`oled_render` | +|`iota_gfx_task` |`oled_task` | +|`iota_gfx_task_user` |`oled_task_user` | diff --git a/feature_pointing_device.md b/feature_pointing_device.md new file mode 100644 index 00000000000..c9309d6975d --- /dev/null +++ b/feature_pointing_device.md @@ -0,0 +1,49 @@ +# Pointing Device :id=pointing-device + +Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and lightweight. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you. + +To enable Pointing Device, uncomment the following line in your rules.mk: + +```makefile +POINTING_DEVICE_ENABLE = yes +``` + +To manipulate the mouse report, you can use the following functions: + +* `pointing_device_get_report()` - Returns the current report_mouse_t that represents the information sent to the host computer +* `pointing_device_set_report(report_mouse_t newMouseReport)` - Overrides and saves the report_mouse_t to be sent to the host computer + +Keep in mind that a report_mouse_t (here "mouseReport") has the following properties: + +* `mouseReport.x` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ to the right, - to the left) on the x axis. +* `mouseReport.y` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ upward, - downward) on the y axis. +* `mouseReport.v` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing vertical scrolling (+ upward, - downward). +* `mouseReport.h` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing horizontal scrolling (+ right, - left). +* `mouseReport.buttons` - this is a uint8_t in which the last 5 bits are used. These bits represent the mouse button state - bit 3 is mouse button 5, and bit 7 is mouse button 1. + +Once you have made the necessary changes to the mouse report, you need to send it: + +* `pointing_device_send()` - Sends the mouse report to the host and zeroes out the report. + +When the mouse report is sent, the x, y, v, and h values are set to 0 (this is done in `pointing_device_send()`, which can be overridden to avoid this behavior). This way, button states persist, but movement will only occur once. For further customization, both `pointing_device_init` and `pointing_device_task` can be overridden. + +In the following example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. Listen, this is an example: + +```c +case MS_SPECIAL: + report_mouse_t currentReport = pointing_device_get_report(); + if (record->event.pressed) { + currentReport.v = 127; + currentReport.h = 127; + currentReport.buttons |= MOUSE_BTN1; // this is defined in report.h + } else { + currentReport.v = -127; + currentReport.h = -127; + currentReport.buttons &= ~MOUSE_BTN1; + } + pointing_device_set_report(currentReport); + pointing_device_send(); + break; +``` + +Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case. diff --git a/feature_ps2_mouse.md b/feature_ps2_mouse.md new file mode 100644 index 00000000000..e549810855a --- /dev/null +++ b/feature_ps2_mouse.md @@ -0,0 +1,306 @@ +# PS/2 Mouse Support :id=ps2-mouse-support + +Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device. + +To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest from a Thinkpad keyboard), identify the function of each pin of the module, and make the necessary circuitry between controller and Trackpoint module. For more information, please refer to [Trackpoint Hardware](https://deskthority.net/wiki/TrackPoint_Hardware) page on Deskthority Wiki. + +There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended). + +## The Circuitry between Trackpoint and Controller :id=the-circuitry-between-trackpoint-and-controller + +To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+. + +``` + + DATA ----------+--------- PIN + | + 4.7K + | +MODULE 5+ --------+--+--------- PWR CONTROLLER + | + 4.7K + | + CLK ------+------------ PIN +``` + + +## Busywait Version :id=busywait-version + +Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible. + +In rules.mk: + +```makefile +PS2_MOUSE_ENABLE = yes +PS2_USE_BUSYWAIT = yes +``` + +In your keyboard config.h: + +```c +#ifdef PS2_USE_BUSYWAIT +# define PS2_CLOCK_PORT PORTD +# define PS2_CLOCK_PIN PIND +# define PS2_CLOCK_DDR DDRD +# define PS2_CLOCK_BIT 1 +# define PS2_DATA_PORT PORTD +# define PS2_DATA_PIN PIND +# define PS2_DATA_DDR DDRD +# define PS2_DATA_BIT 2 +#endif +``` + +## Interrupt Version :id=interrupt-version + +The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data. + +In rules.mk: + +```makefile +PS2_MOUSE_ENABLE = yes +PS2_USE_INT = yes +``` + +In your keyboard config.h: + +```c +#ifdef PS2_USE_INT +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 2 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 5 + +#define PS2_INT_INIT() do { \ + EICRA |= ((1< GND +// 0b1110111 AD <-> VCC +// 0b1110101 AD <-> SCL +// 0b1110110 AD <-> SDA +#define DRIVER_ADDR_1 0b1110100 +#define DRIVER_ADDR_2 0b1110110 + +#define DRIVER_COUNT 2 +#define DRIVER_1_LED_TOTAL 25 +#define DRIVER_2_LED_TOTAL 24 +#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) +``` + +!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. + +Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations. + +Define these arrays listing all the LEDs in your `.c`: + +```c +const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +/* Refer to IS31 manual for these locations + * driver + * | R location + * | | G location + * | | | B location + * | | | | */ + {0, C1_3, C2_3, C3_3}, + .... +} +``` + +Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now). + +--- +### IS31FL3733/IS31FL3737 :id=is31fl3733is31fl3737 + +!> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`. + +There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`: + +```makefile +RGB_MATRIX_ENABLE = IS31FL3733 +``` + +Configure the hardware via your `config.h`: + +```c +// This is a 7-bit address, that gets left-shifted and bit 0 +// set to 0 for write, 1 for read (as per I2C protocol) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define DRIVER_ADDR_1 0b1010000 +#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons. + +#define DRIVER_COUNT 2 +#define DRIVER_1_LED_TOTAL 64 +#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL +``` + +Currently only a single drivers is supported, but it would be trivial to support all 4 combinations. For now define `DRIVER_ADDR_2` as `DRIVER_ADDR_1` + +Define these arrays listing all the LEDs in your `.c`: + +```c +const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +/* Refer to IS31 manual for these locations + * driver + * | R location + * | | G location + * | | | B location + * | | | | */ + {0, B_1, A_1, C_1}, + .... +} +``` + +Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0` right now). + +--- + +### WS2812 :id=ws2812 + +There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`: + +```makefile +RGB_MATRIX_ENABLE = WS2812 +``` + +Configure the hardware via your `config.h`: + +```c +// The pin connected to the data pin of the LEDs +#define RGB_DI_PIN D7 +// The number of LEDs connected +#define DRIVER_LED_TOTAL 70 +``` + +--- + +From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example: + +```c +led_config_t g_led_config = { { + // Key Matrix to LED Index + { 5, NO_LED, NO_LED, 0 }, + { NO_LED, NO_LED, NO_LED, NO_LED }, + { 4, NO_LED, NO_LED, 1 }, + { 3, NO_LED, NO_LED, 2 } +}, { + // LED Index to Physical Position + { 188, 16 }, { 187, 48 }, { 149, 64 }, { 112, 64 }, { 37, 48 }, { 38, 16 } +}, { + // LED Index to Flag + 1, 4, 4, 4, 4, 1 +} }; +``` + +The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position: + +```c +x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION +y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION +``` + +Where NUMBER_OF_COLS, NUMBER_OF_ROWS, COL_POSITION, & ROW_POSITION are all based on the physical layout of your keyboard, not the electrical layout. + +As mentioned earlier, the center of the keyboard by default is expected to be `{ 112, 32 }`, but this can be changed if you want to more accurately calculate the LED's physical `{ x, y }` positions. Keyboard designers can implement `#define RGB_MATRIX_CENTER { 112, 32 }` in their config.h file with the new center point of the keyboard, or where they want it to be allowing more possibilities for the `{ x, y }` values. Do note that the maximum value for x or y is 255, and the recommended maximum is 224 as this gives animations runoff room before they reset. + +`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type. + +## Flags :id=flags + +|Define |Value |Description | +|----------------------------|------|-------------------------------------------------| +|`HAS_FLAGS(bits, flags)` |*n/a* |Evaluates to `true` if `bits` has all `flags` set| +|`HAS_ANY_FLAGS(bits, flags)`|*n/a* |Evaluates to `true` if `bits` has any `flags` set| +|`LED_FLAG_NONE` |`0x00`|If this LED has no flags | +|`LED_FLAG_ALL` |`0xFF`|If this LED has all flags | +|`LED_FLAG_MODIFIER` |`0x01`|If the LED is on a modifier key | +|`LED_FLAG_UNDERGLOW` |`0x02`|If the LED is for underglow | +|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight | +|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication | + +## Keycodes :id=keycodes + +All RGB keycodes are currently shared with the RGBLIGHT system: + +|Key |Aliases |Description | +|-------------------|----------|--------------------------------------------------------------------------------------| +|`RGB_TOG` | |Toggle RGB lighting on or off | +|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | +|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held | +|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | +|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | +|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | +|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | +|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | +|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | +|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held| +|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held| +|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode | +|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | +|`RGB_MODE_RAINBOW` |`RGB_M_R` |Full gradient scrolling left to right (uses the `RGB_MATRIX_CYCLE_LEFT_RIGHT` mode) | +|`RGB_MODE_SWIRL` |`RGB_M_SW`|Full gradient spinning pinwheel around center of keyboard (uses `RGB_MATRIX_CYCLE_PINWHEEL` mode) | + +* `RGB_MODE_*` keycodes will generally work, but not all of the modes are currently mapped to the correct effects for the RGB Matrix system. + +`RGB_MODE_PLAIN`, `RGB_MODE_BREATHE`, `RGB_MODE_RAINBOW`, and `RGB_MATRIX_SWIRL` are the only ones that are mapped properly. The rest don't have a direct equivalent, and are not mapped. + +!> By default, if you have both the [RGB Light](feature_rgblight.md) and the RGB Matrix feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature. + +## RGB Matrix Effects :id=rgb-matrix-effects + +All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available: + +```c +enum rgb_matrix_effects { + RGB_MATRIX_NONE = 0, + RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support + RGB_MATRIX_ALPHAS_MODS, // Static dual hue, speed is hue for secondary hue + RGB_MATRIX_GRADIENT_UP_DOWN, // Static gradient top to bottom, speed controls how much gradient changes + RGB_MATRIX_GRADIENT_LEFT_RIGHT, // Static gradient left to right, speed controls how much gradient changes + RGB_MATRIX_BREATHING, // Single hue brightness cycling animation + RGB_MATRIX_BAND_SAT, // Single hue band fading saturation scrolling left to right + RGB_MATRIX_BAND_VAL, // Single hue band fading brightness scrolling left to right + RGB_MATRIX_BAND_PINWHEEL_SAT, // Single hue 3 blade spinning pinwheel fades saturation + RGB_MATRIX_BAND_PINWHEEL_VAL, // Single hue 3 blade spinning pinwheel fades brightness + RGB_MATRIX_BAND_SPIRAL_SAT, // Single hue spinning spiral fades saturation + RGB_MATRIX_BAND_SPIRAL_VAL, // Single hue spinning spiral fades brightness + RGB_MATRIX_CYCLE_ALL, // Full keyboard solid hue cycling through full gradient + RGB_MATRIX_CYCLE_LEFT_RIGHT, // Full gradient scrolling left to right + RGB_MATRIX_CYCLE_UP_DOWN, // Full gradient scrolling top to bottom + RGB_MATRIX_CYCLE_OUT_IN, // Full gradient scrolling out to in + RGB_MATRIX_CYCLE_OUT_IN_DUAL, // Full dual gradients scrolling out to in + RGB_MATRIX_RAINBOW_MOVING_CHEVRON, // Full gradent Chevron shapped scrolling left to right + RGB_MATRIX_CYCLE_PINWHEEL, // Full gradient spinning pinwheel around center of keyboard + RGB_MATRIX_CYCLE_SPIRAL, // Full gradient spinning spiral around center of keyboard + RGB_MATRIX_DUAL_BEACON, // Full gradient spinning around center of keyboard + RGB_MATRIX_RAINBOW_BEACON, // Full tighter gradient spinning around center of keyboard + RGB_MATRIX_RAINBOW_PINWHEELS, // Full dual gradients spinning two halfs of keyboard + RGB_MATRIX_RAINDROPS, // Randomly changes a single key's hue + RGB_MATRIX_JELLYBEAN_RAINDROPS, // Randomly changes a single key's hue and saturation +#if define(RGB_MATRIX_FRAMEBUFFER_EFFECTS) + RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM! + RGB_MATRIX_DIGITAL_RAIN, // That famous computer simulation +#endif +#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES) + RGB_MATRIX_SOLID_REACTIVE_SIMPLE, // Pulses keys hit to hue & value then fades value out + RGB_MATRIX_SOLID_REACTIVE, // Static single hue, pulses keys hit to shifted hue then fades to current hue + RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out + RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out + RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out + RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out + RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out + RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out + RGB_MATRIX_SPLASH, // Full gradient & value pulse away from a single key hit then fades value out + RGB_MATRIX_MULTISPLASH, // Full gradient & value pulse away from multiple key hits then fades value out + RGB_MATRIX_SOLID_SPLASH, // Hue & value pulse away from a single key hit then fades value out + RGB_MATRIX_SOLID_MULTISPLASH, // Hue & value pulse away from multiple key hits then fades value out +#endif + RGB_MATRIX_EFFECT_MAX +}; +``` + +You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `config.h`: + + +|Define |Description | +|-------------------------------------------------------|-----------------------------------------------| +|`#define DISABLE_RGB_MATRIX_ALPHAS_MODS` |Disables `RGB_MATRIX_ALPHAS_MODS` | +|`#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN` |Disables `RGB_MATRIX_GRADIENT_UP_DOWN` | +|`#define DISABLE_RGB_MATRIX_BREATHING` |Disables `RGB_MATRIX_BREATHING` | +|`#define DISABLE_RGB_MATRIX_BAND_SAT` |Disables `RGB_MATRIX_BAND_SAT` | +|`#define DISABLE_RGB_MATRIX_BAND_VAL` |Disables `RGB_MATRIX_BAND_VAL` | +|`#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT` |Disables `RGB_MATRIX_BAND_PINWHEEL_SAT` | +|`#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL` |Disables `RGB_MATRIX_BAND_PINWHEEL_VAL` | +|`#define DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT` |Disables `RGB_MATRIX_BAND_SPIRAL_SAT` | +|`#define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL` |Disables `RGB_MATRIX_BAND_SPIRAL_VAL` | +|`#define DISABLE_RGB_MATRIX_CYCLE_ALL` |Disables `RGB_MATRIX_CYCLE_ALL` | +|`#define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT` |Disables `RGB_MATRIX_CYCLE_LEFT_RIGHT` | +|`#define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN` |Disables `RGB_MATRIX_CYCLE_UP_DOWN` | +|`#define DISABLE_RGB_MATRIX_CYCLE_OUT_IN` |Disables `RGB_MATRIX_CYCLE_OUT_IN` | +|`#define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL` |Disables `RGB_MATRIX_CYCLE_OUT_IN_DUAL` | +|`#define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON` |Disables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON` | +|`#define DISABLE_RGB_MATRIX_DUAL_BEACON` |Disables `RGB_MATRIX_DUAL_BEACON` | +|`#define DISABLE_RGB_MATRIX_CYCLE_PINWHEEL` |Disables `RGB_MATRIX_CYCLE_PINWHEEL` | +|`#define DISABLE_RGB_MATRIX_CYCLE_SPIRAL` |Disables `RGB_MATRIX_CYCLE_SPIRAL` | +|`#define DISABLE_RGB_MATRIX_RAINBOW_BEACON` |Disables `RGB_MATRIX_RAINBOW_BEACON` | +|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS` |Disables `RGB_MATRIX_RAINBOW_PINWHEELS` | +|`#define DISABLE_RGB_MATRIX_RAINDROPS` |Disables `RGB_MATRIX_RAINDROPS` | +|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS` |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS` | +|`#define DISABLE_RGB_MATRIX_TYPING_HEATMAP` |Disables `RGB_MATRIX_TYPING_HEATMAP` | +|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN` |Disables `RGB_MATRIX_DIGITAL_RAIN` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE` |Disables `RGB_MATRIX_SOLID_REACTIVE` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |Disables `RGB_MATRIX_SOLID_REACTIVE_SIMPLE` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE` |Disables `RGB_MATRIX_SOLID_REACTIVE_WIDE` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE` |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS` |Disables `RGB_MATRIX_SOLID_REACTIVE_CROSS` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS` |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTICROSS`| +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS` |Disables `RGB_MATRIX_SOLID_REACTIVE_NEXUS` | +|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS` |Disables `RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS`| +|`#define DISABLE_RGB_MATRIX_SPLASH` |Disables `RGB_MATRIX_SPLASH` | +|`#define DISABLE_RGB_MATRIX_MULTISPLASH` |Disables `RGB_MATRIX_MULTISPLASH` | +|`#define DISABLE_RGB_MATRIX_SOLID_SPLASH` |Disables `RGB_MATRIX_SOLID_SPLASH` | +|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Disables `RGB_MATRIX_SOLID_MULTISPLASH` | + + +## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects + +By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files. + +To declare new effects, create a new `rgb_matrix_user/kb.inc` that looks something like this: + +`rgb_matrix_user.inc` should go in the root of the keymap directory. +`rgb_matrix_kb.inc` should go in the root of the keyboard directory. + +```c +// !!! DO NOT ADD #pragma once !!! // + +// Step 1. +// Declare custom effects using the RGB_MATRIX_EFFECT macro +// (note the lack of semicolon after the macro!) +RGB_MATRIX_EFFECT(my_cool_effect) +RGB_MATRIX_EFFECT(my_cool_effect2) + +// Step 2. +// Define effects inside the `RGB_MATRIX_CUSTOM_EFFECT_IMPLS` ifdef block +#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +// e.g: A simple effect, self-contained within a single method +static bool my_cool_effect(effect_params_t* params) { + RGB_MATRIX_USE_LIMITS(led_min, led_max); + for (uint8_t i = led_min; i < led_max; i++) { + rgb_matrix_set_color(i, 0xff, 0xff, 0x00); + } + return led_max < DRIVER_LED_TOTAL; +} + +// e.g: A more complex effect, relying on external methods and state, with +// dedicated init and run methods +static uint8_t some_global_state; +static void my_cool_effect2_complex_init(effect_params_t* params) { + some_global_state = 1; +} +static bool my_cool_effect2_complex_run(effect_params_t* params) { + RGB_MATRIX_USE_LIMITS(led_min, led_max); + for (uint8_t i = led_min; i < led_max; i++) { + rgb_matrix_set_color(i, 0xff, some_global_state++, 0xff); + } + + return led_max < DRIVER_LED_TOTAL; +} +static bool my_cool_effect2(effect_params_t* params) { + if (params->init) my_cool_effect2_complex_init(params); + return my_cool_effect2_complex_run(params); +} + +#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS +``` + +For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/` + + +## Colors :id=colors + +These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. + +|RGB |HSV | +|-------------------|-------------------| +|`RGB_WHITE` |`HSV_WHITE` | +|`RGB_RED` |`HSV_RED` | +|`RGB_CORAL` |`HSV_CORAL` | +|`RGB_ORANGE` |`HSV_ORANGE` | +|`RGB_GOLDENROD` |`HSV_GOLDENROD` | +|`RGB_GOLD` |`HSV_GOLD` | +|`RGB_YELLOW` |`HSV_YELLOW` | +|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | +|`RGB_GREEN` |`HSV_GREEN` | +|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | +|`RGB_TURQUOISE` |`HSV_TURQUOISE` | +|`RGB_TEAL` |`HSV_TEAL` | +|`RGB_CYAN` |`HSV_CYAN` | +|`RGB_AZURE` |`HSV_AZURE` | +|`RGB_BLUE` |`HSV_BLUE` | +|`RGB_PURPLE` |`HSV_PURPLE` | +|`RGB_MAGENTA` |`HSV_MAGENTA` | +|`RGB_PINK` |`HSV_PINK` | + +These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list! + + +## Additional `config.h` Options :id=additional-configh-options + +```c +#define RGB_MATRIX_KEYPRESSES // reacts to keypresses +#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) +#define RGB_DISABLE_TIMEOUT 0 // number of milliseconds to wait until rgb automatically turns off +#define RGB_DISABLE_AFTER_TIMEOUT 0 // OBSOLETE: number of ticks to wait until disabling effects +#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended +#define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) +#define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) +#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255 +#define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set +#define RGB_MATRIX_STARTUP_HUE 0 // Sets the default hue value, if none has been set +#define RGB_MATRIX_STARTUP_SAT 255 // Sets the default saturation value, if none has been set +#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set +#define RGB_MATRIX_STARTUP_SPD 127 // Sets the default animation speed, if none has been set +#define RGB_MATRIX_DISABLE_KEYCODES // disables control of rgb matrix by keycodes (must use code functions to control the feature) +``` + +## EEPROM storage :id=eeprom-storage + +The EEPROM for it is currently shared with the RGBLIGHT system (it's generally assumed only one RGB would be used at a time), but could be configured to use its own 32bit address with: + +```c +#define EECONFIG_RGB_MATRIX (uint32_t *)28 +``` + +Where `28` is an unused index from `eeconfig.h`. + +## Functions :id=functions + +### Direct Operation :id=direct-operation +|Function |Description | +|--------------------------------------------|-------------| +|`rgb_matrix_set_color_all(r, g, b)` |Set all of the LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | +|`rgb_matrix_set_color(index, r, g, b)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255, and `index` is between 0 and `DRIVER_LED_TOTAL` (not written to EEPROM) | + +### Disable/Enable Effects :id=disable-enable-effects +|Function |Description | +|--------------------------------------------|-------------| +|`rgb_matrix_toggle()` |Toggle effect range LEDs between on and off | +|`rgb_matrix_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) | +|`rgb_matrix_enable()` |Turn effect range LEDs on, based on their previous state | +|`rgb_matrix_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) | +|`rgb_matrix_disable()` |Turn effect range LEDs off, based on their previous state | +|`rgb_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) | + +### Change Effect Mode :id=change-effect-mode +|Function |Description | +|--------------------------------------------|-------------| +|`rgb_matrix_mode(mode)` |Set the mode, if RGB animations are enabled | +|`rgb_matrix_mode_noeeprom(mode)` |Set the mode, if RGB animations are enabled (not written to EEPROM) | +|`rgb_matrix_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations | +|`rgb_matrix_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) | +|`rgb_matrix_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations | +|`rgb_matrix_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) | +|`rgb_matrix_increase_speed()` |Increase the speed of the animations | +|`rgb_matrix_increase_speed_noeeprom()` |Increase the speed of the animations (not written to EEPROM) | +|`rgb_matrix_decrease_speed()` |Decrease the speed of the animations | +|`rgb_matrix_decrease_speed_noeeprom()` |Decrease the speed of the animations (not written to EEPROM) | +|`rgb_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 | +|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) | + +### Change Color :id=change-color +|Function |Description | +|--------------------------------------------|-------------| +|`rgb_matrix_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue | +|`rgb_matrix_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) | +|`rgb_matrix_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue | +|`rgb_matrix_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) | +|`rgb_matrix_increase_sat()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation | +|`rgb_matrix_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation (not written to EEPROM) | +|`rgb_matrix_decrease_sat()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation | +|`rgb_matrix_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation (not written to EEPROM) | +|`rgb_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value | +|`rgb_matrix_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) | +|`rgb_matrix_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value | +|`rgb_matrix_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) | +|`rgb_matrix_sethsv(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 | +|`rgb_matrix_sethsv_noeeprom(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | + +### Query Current Status :id=query-current-status +|Function |Description | +|---------------------------------|---------------------------| +|`rgb_matrix_is_enabled()` |Gets current on/off status | +|`rgb_matrix_get_mode()` |Gets current mode | +|`rgb_matrix_get_hue()` |Gets current hue | +|`rgb_matrix_get_sat()` |Gets current sat | +|`rgb_matrix_get_val()` |Gets current val | +|`rgb_matrix_get_hsv()` |Gets hue, sat, and val and returns a [`HSV` structure](https://github.com/qmk/qmk_firmware/blob/7ba6456c0b2e041bb9f97dbed265c5b8b4b12192/quantum/color.h#L56-L61)| +|`rgb_matrix_get_speed()` |Gets current speed | +|`rgb_matrix_get_suspend_state()` |Gets current suspend state | + +## Callbacks :id=callbacks + +### Indicators :id=indicators + +If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, you can use the `rgb_matrix_indicators_kb` or `rgb_matrix_indicators_user` function for that: +```c +void rgb_matrix_indicators_kb(void) { + rgb_matrix_set_color(index, red, green, blue); +} +``` + +### Suspended state :id=suspended-state +To use the suspend feature, make sure that `#define RGB_DISABLE_WHEN_USB_SUSPENDED true` is added to the `config.h` file. + +Additionally add this to your `.c`: + +```c +void suspend_power_down_kb(void) { + rgb_matrix_set_suspend_state(true); + suspend_power_down_user(); +} + +void suspend_wakeup_init_kb(void) { + rgb_matrix_set_suspend_state(false); + suspend_wakeup_init_user(); +} +``` +or add this to your `keymap.c`: +```c +void suspend_power_down_user(void) { + rgb_matrix_set_suspend_state(true); +} + +void suspend_wakeup_init_user(void) { + rgb_matrix_set_suspend_state(false); +} +``` diff --git a/feature_rgblight.md b/feature_rgblight.md new file mode 100644 index 00000000000..762056b3432 --- /dev/null +++ b/feature_rgblight.md @@ -0,0 +1,520 @@ +# RGB Lighting + +QMK has the ability to control RGB LEDs attached to your keyboard. This is commonly called *underglow*, due to the LEDs often being mounted on the bottom of the keyboard, producing a nice diffused effect when combined with a translucent case. + +![Planck with RGB Underglow](https://raw.githubusercontent.com/qmk/qmk_firmware/3774a7fcdab5544fc787f4c200be05fcd417e31f/keyboards/planck/keymaps/yang/planck-with-rgb-underglow.jpg) + +Some keyboards come with RGB LEDs preinstalled. Others must have them installed after the fact. See the [Hardware Modification](#hardware-modification) section for information on adding RGB lighting to your keyboard. + +Currently QMK supports the following addressable LEDs (however, the white LED in RGBW variants is not supported): + + * WS2811, WS2812, WS2812B, WS2812C, etc. + * SK6812, SK6812MINI, SK6805 + +These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs. + +## Usage + +On keyboards with onboard RGB LEDs, it is usually enabled by default. If it is not working for you, check that your `rules.mk` includes the following: + +```make +RGBLIGHT_ENABLE = yes +``` + +At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these. + +|Define |Description | +|---------------|---------------------------------------------------------------------------------------------------------| +|`RGB_DI_PIN` |The pin connected to the data pin of the LEDs | +|`RGBLED_NUM` |The number of LEDs connected | +|`RGBLED_SPLIT` |(Optional) For split keyboards, the number of LEDs connected on each half directly wired to `RGB_DI_PIN` | + +Then you should be able to use the keycodes below to change the RGB lighting to your liking. + +### Color Selection + +QMK uses [Hue, Saturation, and Value](https://en.wikipedia.org/wiki/HSL_and_HSV) to select colors rather than RGB. The color wheel below demonstrates how this works. + +HSV Color Wheel + +Changing the **Hue** cycles around the circle.
+Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.
+Changing the **Value** sets the overall brightness.
+ +![QMK Color Wheel with HSV Values](https://i.imgur.com/vkYVo66.jpg) + +## Keycodes + +|Key |Aliases |Description | +|-------------------|----------|--------------------------------------------------------------------| +|`RGB_TOG` | |Toggle RGB lighting on or off | +|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | +|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held| +|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | +|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | +|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | +|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | +|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | +|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | +|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode | +|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | +|`RGB_MODE_RAINBOW` |`RGB_M_R` |Rainbow animation mode | +|`RGB_MODE_SWIRL` |`RGB_M_SW`|Swirl animation mode | +|`RGB_MODE_SNAKE` |`RGB_M_SN`|Snake animation mode | +|`RGB_MODE_KNIGHT` |`RGB_M_K` |"Knight Rider" animation mode | +|`RGB_MODE_XMAS` |`RGB_M_X` |Christmas animation mode | +|`RGB_MODE_GRADIENT`|`RGB_M_G` |Static gradient animation mode | +|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode | + +!> By default, if you have both the RGB Light and the [RGB Matrix](feature_rgb_matrix.md) feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature. + + +## Configuration + +Your RGB lighting can be configured by placing these `#define`s in your `config.h`: + +|Define |Default |Description | +|---------------------|-------------|-----------------------------------------------------------------------------| +|`RGBLIGHT_HUE_STEP` |`10` |The number of steps to cycle through the hue by | +|`RGBLIGHT_SAT_STEP` |`17` |The number of steps to increment the saturation by | +|`RGBLIGHT_VAL_STEP` |`17` |The number of steps to increment the brightness by | +|`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level | +|`RGBLIGHT_SLEEP` |*Not defined*|If defined, the RGB lighting will be switched off when the host goes to sleep| +|`RGBLIGHT_SPLIT` |*Not defined*|If defined, synchronization functionality for split keyboards is added| +|`RGBLIGHT_DISABLE_KEYCODES`|*not defined*|If defined, disables the ability to control RGB Light from the keycodes. You must use code functions to control the feature| + +## Effects and Animations + +Not only can this lighting be whatever color you want, +if `RGBLIGHT_EFFECT_xxxx` or `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal: + +|Mode number symbol |Additional number |Description | +|-----------------------------|-------------------|---------------------------------------| +|`RGBLIGHT_MODE_STATIC_LIGHT` | *None* |Solid color (this mode is always enabled) | +|`RGBLIGHT_MODE_BREATHING` | 0,1,2,3 |Solid color breathing | +|`RGBLIGHT_MODE_RAINBOW_MOOD` | 0,1,2 |Cycling rainbow | +|`RGBLIGHT_MODE_RAINBOW_SWIRL`| 0,1,2,3,4,5 |Swirling rainbow | +|`RGBLIGHT_MODE_SNAKE` | 0,1,2,3,4,5 |Snake | +|`RGBLIGHT_MODE_KNIGHT` | 0,1,2 |Knight | +|`RGBLIGHT_MODE_CHRISTMAS` | *None* |Christmas | +|`RGBLIGHT_MODE_STATIC_GRADIENT`| 0,1,..,9 |Static gradient | +|`RGBLIGHT_MODE_RGB_TEST` | *None* |RGB Test | +|`RGBLIGHT_MODE_ALTERNATING` | *None* |Alternating | +|`RGBLIGHT_MODE_TWINKLE` | 0,1,2,3,4,5 |Twinkle | + +Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration. + +Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight.h` there is a contrast table between the old mode number and the current symbol. + +### Effect and Animation Toggles + +Use these defines to add or remove animations from the firmware. When you are running low on flash space, it can be helpful to disable animations you are not using. + +|Define |Default |Description | +|------------------------------------|-------------|-------------------------------------------------------------------------| +|`RGBLIGHT_ANIMATIONS` |*Not defined*|Enable all additional animation modes. | +|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|Enable alternating animation mode. | +|`RGBLIGHT_EFFECT_BREATHING` |*Not defined*|Enable breathing animation mode. | +|`RGBLIGHT_EFFECT_CHRISTMAS` |*Not defined*|Enable christmas animation mode. | +|`RGBLIGHT_EFFECT_KNIGHT` |*Not defined*|Enable knight animation mode. | +|`RGBLIGHT_EFFECT_RAINBOW_MOOD` |*Not defined*|Enable rainbow mood animation mode. | +|`RGBLIGHT_EFFECT_RAINBOW_SWIRL` |*Not defined*|Enable rainbow swirl animation mode. | +|`RGBLIGHT_EFFECT_RGB_TEST` |*Not defined*|Enable RGB test animation mode. | +|`RGBLIGHT_EFFECT_SNAKE` |*Not defined*|Enable snake animation mode. | +|`RGBLIGHT_EFFECT_STATIC_GRADIENT` |*Not defined*|Enable static gradient mode. | +|`RGBLIGHT_EFFECT_TWINKLE` |*Not defined*|Enable twinkle animation mode. | + +### Effect and Animation Settings + +The following options are used to tweak the various animations: + +|Define |Default |Description | +|------------------------------------|-------------|-----------------------------------------------------------------------------------------------| +|`RGBLIGHT_EFFECT_BREATHE_CENTER` |*Not defined*|If defined, used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 | +|`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 | +|`RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL`|`40` |How long (in milliseconds) to wait between animation steps for the "Christmas" animation | +|`RGBLIGHT_EFFECT_CHRISTMAS_STEP` |`2` |The number of LEDs to group the red/green colors by for the "Christmas" animation | +|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel | +|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation | +|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by | +|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`255` |Range adjustment for the rainbow swirl effect to get different swirls | +|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation | +|`RGBLIGHT_EFFECT_TWINKLE_LIFE` |`75` |Adjusts how quickly each LED brightens and dims when twinkling (in animation steps) | +|`RGBLIGHT_EFFECT_TWINKLE_PROBABILITY`|`1/127` |Adjusts how likely each LED is to twinkle (on each animation step) | + +### Example Usage to Reduce Memory Footprint + 1. Remove `RGBLIGHT_ANIMATIONS` from `config.h`. + 1. Selectively add the animations you want to enable. The following would enable two animations and save about 4KiB: + +```diff + #undef RGBLED_NUM +-#define RGBLIGHT_ANIMATIONS ++#define RGBLIGHT_EFFECT_STATIC_GRADIENT ++#define RGBLIGHT_EFFECT_RAINBOW_SWIRL + #define RGBLED_NUM 12 + #define RGBLIGHT_HUE_STEP 8 + #define RGBLIGHT_SAT_STEP 8 +``` + +### Animation Speed + +You can also modify the speeds that the different modes animate at: + +Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY). + +```c +// How long (in milliseconds) to wait between animation steps for each of the "Solid color breathing" animations +const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; + +// How long (in milliseconds) to wait between animation steps for each of the "Cycling rainbow" animations +const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; + +// How long (in milliseconds) to wait between animation steps for each of the "Swirling rainbow" animations +const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; + +// How long (in milliseconds) to wait between animation steps for each of the "Snake" animations +const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; + +// How long (in milliseconds) to wait between animation steps for each of the "Knight" animations +const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; + +// How long (in milliseconds) to wait between animation steps for each of the "Twinkle" animations +const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {50, 25, 10}; + +// These control which hues are selected for each of the "Static gradient" modes +const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64}; +``` + +## Lighting Layers + +By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make +it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do. + +### Defining Lighting Layers :id=defining-lighting-layers + +By default, 8 layers are possible. This can be expanded to as many as 32 by overriding the definition of `RGBLIGHT_MAX_LAYERS` in `config.h` (e.g. `#define RGBLIGHT_MAX_LAYERS 32`). Please note, if you use a split keyboard, you will need to flash both sides of the split after changing this. Also, increasing the maximum will increase the firmware size, and will slow sync on split keyboards. + +To define a layer, we modify `keymap.c` to list out LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently: + +```c +// Light LEDs 6 to 9 and 12 to 15 red when caps lock is active. Hard to ignore! +const rgblight_segment_t PROGMEM my_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS( + {6, 4, HSV_RED}, // Light 4 LEDs, starting with LED 6 + {12, 4, HSV_RED} // Light 4 LEDs, starting with LED 12 +); +// Light LEDs 9 & 10 in cyan when keyboard layer 1 is active +const rgblight_segment_t PROGMEM my_layer1_layer[] = RGBLIGHT_LAYER_SEGMENTS( + {9, 2, HSV_CYAN} +); +// Light LEDs 11 & 12 in purple when keyboard layer 2 is active +const rgblight_segment_t PROGMEM my_layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS( + {11, 2, HSV_PURPLE} +); +// etc.. +``` + +We combine these layers into an array using the `RGBLIGHT_LAYERS_LIST` macro, and assign it to the `rgblight_layers` variable during keyboard setup. Note that you can only define up to 8 lighting layers. Any extra layers will be ignored. Since the different lighting layers overlap, the order matters in the array, with later layers taking precedence: + +```c +// Now define the array of layers. Later layers take precedence +const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST( + my_capslock_layer, + my_layer1_layer, // Overrides caps lock layer + my_layer2_layer // Overrides other layers +); + +void keyboard_post_init_user(void) { + // Enable the LED layers + rgblight_layers = my_rgb_layers; +} +``` +Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers. + +### Enabling and disabling lighting layers :id=enabling-lighting-layers + +Everything above just configured the definition of each lighting layer. +We can now enable and disable the lighting layers whenever the state of the keyboard changes: + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + // Both layers will light up if both kb layers are active + rgblight_set_layer_state(1, layer_state_cmp(state, 1)); + rgblight_set_layer_state(2, layer_state_cmp(state, 2)); + return state; +} + +bool led_update_user(led_t led_state) { + rgblight_set_layer_state(0, led_state.caps_lock); + return true; +} +``` + +### Lighting layer blink :id=lighting-layer-blink + +By including `#define RGBLIGHT_LAYER_BLINK` in your `config.h` file you can turn a lighting +layer on for a specified duration. Once the specified number of milliseconds has elapsed +the layer will be turned off. This is useful, e.g., if you want to acknowledge some +action (e.g. toggling some setting): + +```c +const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_GREEN} ); +const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_RED} ); + +const rgblight_segment_t* const PROGMEM _rgb_layers[] = + RGBLIGHT_LAYERS_LIST( _yes_layer, _no_layer ); + +void keyboard_post_init_user(void) { + rgblight_layers = _rgb_layers; +} + +// Note we user post_process_record_user because we want the state +// after the flag has been flipped... +void post_process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case DEBUG: + rgblight_blink_layer(debug_enable ? 0 : 1, 500); + break; + + case NK_TOGG: + case NK_ON: + case NK_OFF: + rgblight_blink_layer(keymap_config.nkro ? 0 : 1, 500); + break; + } +} +``` + +### Overriding RGB Lighting on/off status + +Normally lighting layers are not shown when RGB Lighting is disabled (e.g. with `RGB_TOG` keycode). If you would like lighting layers to work even when the RGB Lighting is otherwise off, add `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` to your `config.h`. + +## Functions + +If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include: + +### Utility Functions +|Function |Description | +|--------------------------------------------|-------------------------------------------------------------------| +|`sethsv(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value | +|`sethsv_raw(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value without RGBLIGHT_LIMIT_VAL check | +|`setrgb(r, g, b, ledbuf)` |Set ledbuf to the given RGB value where `r`/`g`/`b` | + +### Low level Functions +|Function |Description | +|--------------------------------------------|-------------------------------------------| +|`rgblight_set()` |Flash out led buffers to LEDs | +|`rgblight_set_clipping_range(pos, num)` |Set clipping Range. see [Clipping Range](#clipping-range) | + +Example: +```c +sethsv(HSV_WHITE, (LED_TYPE *)&led[0]); // led 0 +sethsv(HSV_RED, (LED_TYPE *)&led[1]); // led 1 +sethsv(HSV_GREEN, (LED_TYPE *)&led[2]); // led 2 +rgblight_set(); // Utility functions do not call rgblight_set() automatically, so they need to be called explicitly. +``` + +### Effects and Animations Functions +#### effect range setting +|Function |Description | +|--------------------------------------------|------------------| +|`rgblight_set_effect_range(pos, num)` |Set Effects Range | + +#### direct operation +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_setrgb_at(r, g, b, index)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) | +|`rgblight_sethsv_at(h, s, v, index)` |Set a single LED to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) | +|`rgblight_setrgb_range(r, g, b, start, end)`|Set a continuous range of LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| +|`rgblight_sethsv_range(h, s, v, start, end)`|Set a continuous range of LEDs to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| +|`rgblight_setrgb(r, g, b)` |Set effect range LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | +|`rgblight_setrgb_master(r, g, b)` |Set the LEDs on the master side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | +|`rgblight_setrgb_slave(r, g, b)` |Set the LEDs on the slave side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | +|`rgblight_sethsv_master(h, s, v)` |Set the LEDs on the master side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | +|`rgblight_sethsv_slave(h, s, v)` |Set the LEDs on the slave side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | + +Example: +```c +rgblight_sethsv(HSV_WHITE, 0); // led 0 +rgblight_sethsv(HSV_RED, 1); // led 1 +rgblight_sethsv(HSV_GREEN, 2); // led 2 +// The above functions automatically calls rgblight_set(), so there is no need to call it explicitly. +// Note that it is inefficient to call repeatedly. +``` + +#### effect mode change +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled | +|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) | +|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations | +|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) | +|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations | +|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) | + +#### effects mode disable/enable +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_toggle()` |Toggle effect range LEDs between on and off | +|`rgblight_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) | +|`rgblight_enable()` |Turn effect range LEDs on, based on their previous state | +|`rgblight_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) | +|`rgblight_disable()` |Turn effect range LEDs off | +|`rgblight_disable_noeeprom()` |Turn effect range LEDs off (not written to EEPROM) | + +#### hue, sat, val change +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue | +|`rgblight_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) | +|`rgblight_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue | +|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) | +|`rgblight_increase_sat()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation | +|`rgblight_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation (not written to EEPROM) | +|`rgblight_decrease_sat()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation | +|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation (not written to EEPROM) | +|`rgblight_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value | +|`rgblight_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) | +|`rgblight_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value | +|`rgblight_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) | +|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 | +|`rgblight_sethsv_noeeprom(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | + +#### Speed functions +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_increase_speed()` |Increases the animation speed | +|`rgblight_increase_speed_noeeprom()` |Increases the animation speed (not written to EEPROM) | +|`rgblight_decrease_speed()` |Decreases the animation speed | +|`rgblight_decrease_speed_noeeprom()` |Decreases the animation speed (not written to EEPROM) | +|`rgblight_set_speed()` |Sets the speed. Value is between 0 and 255 | +|`rgblight_set_speed_noeeprom()` |Sets the speed. Value is between 0 and 255 (not written to EEPROM) | + + +#### layer functions +|Function |Description | +|--------------------------------------------|-------------| +|`rgblight_get_layer_state(i)` |Returns `true` if lighting layer `i` is enabled | +|`rgblight_set_layer_state(i, is_on)` |Enable or disable lighting layer `i` based on value of `bool is_on` | + +#### query +|Function |Description | +|-----------------------|---------------------------| +|`rgblight_is_enabled()`|Gets current on/off status | +|`rgblight_get_mode()` |Gets current mode | +|`rgblight_get_hue()` |Gets current hue | +|`rgblight_get_sat()` |Gets current sat | +|`rgblight_get_val()` |Gets current val | +|`rgblight_get_speed()` |Gets current speed | + +## Colors + +These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. + +|RGB |HSV | +|-------------------|-------------------| +|`RGB_WHITE` |`HSV_WHITE` | +|`RGB_RED` |`HSV_RED` | +|`RGB_CORAL` |`HSV_CORAL` | +|`RGB_ORANGE` |`HSV_ORANGE` | +|`RGB_GOLDENROD` |`HSV_GOLDENROD` | +|`RGB_GOLD` |`HSV_GOLD` | +|`RGB_YELLOW` |`HSV_YELLOW` | +|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | +|`RGB_GREEN` |`HSV_GREEN` | +|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | +|`RGB_TURQUOISE` |`HSV_TURQUOISE` | +|`RGB_TEAL` |`HSV_TEAL` | +|`RGB_CYAN` |`HSV_CYAN` | +|`RGB_AZURE` |`HSV_AZURE` | +|`RGB_BLUE` |`HSV_BLUE` | +|`RGB_PURPLE` |`HSV_PURPLE` | +|`RGB_MAGENTA` |`HSV_MAGENTA` | +|`RGB_PINK` |`HSV_PINK` | + +```c +rgblight_setrgb(RGB_ORANGE); +rgblight_sethsv_noeeprom(HSV_GREEN); +rgblight_setrgb_at(RGB_GOLD, 3); +rgblight_sethsv_range(HSV_WHITE, 0, 6); +``` + +These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list! + + +## Changing the order of the LEDs + +If you want to make the logical order of LEDs different from the electrical connection order, you can do this by defining the `RGBLIGHT_LED_MAP` macro in your `config.h`. + +Normally, the contents of the LED buffer are output to the LEDs in the same order. +simple dicrect + +By defining `RGBLIGHT_LED_MAP` as in the example below, you can specify the LED with addressing in reverse order of the electrical connection order. + +```c +// config.h + +#define RGBLED_NUM 4 +#define RGBLIGHT_LED_MAP { 3, 2, 1, 0 } + +``` +simple mapped + +For keyboards that use the RGB LEDs as a backlight for each key, you can also define it as in the example below. + +```c +// config.h + +#define RGBLED_NUM 30 + +/* RGB LED Conversion macro from physical array to electric array */ +#define LED_LAYOUT( \ + L00, L01, L02, L03, L04, L05, \ + L10, L11, L12, L13, L14, L15, \ + L20, L21, L22, L23, L24, L25, \ + L30, L31, L32, L33, L34, L35, \ + L40, L41, L42, L43, L44, L45 ) \ + { \ + L05, L04, L03, L02, L01, L00, \ + L10, L11, L12, L13, L14, L15, \ + L25, L24, L23, L22, L21, L20, \ + L30, L31, L32, L33, L34, L35, \ + L46, L45, L44, L43, L42, L41 \ + } + +/* RGB LED logical order map */ +/* Top->Bottom, Right->Left */ +#define RGBLIGHT_LED_MAP LED_LAYOUT( \ + 25, 20, 15, 10, 5, 0, \ + 26, 21, 16, 11, 6, 1, \ + 27, 22, 17, 12, 7, 2, \ + 28, 23, 18, 13, 8, 3, \ + 29, 24, 19, 14, 9, 4 ) + +``` +## Clipping Range + +Using the `rgblight_set_clipping_range()` function, you can prepare more buffers than the actual number of LEDs, and output some of the buffers to the LEDs. This is useful if you want the split keyboard to treat left and right LEDs as logically contiguous. + +You can set the Clipping Range by executing the following code. + +```c +// some source +rgblight_set_clipping_range(3, 4); +``` +clip direct + +In addition to setting the Clipping Range, you can use `RGBLIGHT_LED_MAP` together. + +```c +// config.h +#define RGBLED_NUM 8 +#define RGBLIGHT_LED_MAP { 7, 6, 5, 4, 3, 2, 1, 0 } + +// some soruce + rgblight_set_clipping_range(3, 4); +``` +clip mapped + +## Hardware Modification + +If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins. diff --git a/feature_space_cadet.md b/feature_space_cadet.md new file mode 100644 index 00000000000..41a44627e3c --- /dev/null +++ b/feature_space_cadet.md @@ -0,0 +1,60 @@ +# Space Cadet: The Future, Built In + +Steve Losh described the [Space Cadet Shift](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) quite well. Essentially, when you tap Left Shift on its own, you get an opening parenthesis; tap Right Shift on its own and you get the closing one. When held, the Shift keys function as normal. Yes, it's as cool as it sounds, and now even cooler supporting Control and Alt as well! + +## Usage + +Firstly, in your keymap, do one of the following: +- Replace the Left Shift key with `KC_LSPO` (Left Shift, Parenthesis Open), and Right Shift with `KC_RSPC` (Right Shift, Parenthesis Close). +- Replace the Left Control key with `KC_LCPO` (Left Control, Parenthesis Open), and Right Control with `KC_RCPC` (Right Control, Parenthesis Close). +- Replace the Left Alt key with `KC_LAPO` (Left Alt, Parenthesis Open), and Right Alt with `KC_RAPC` (Right Alt, Parenthesis Close). +- Replace any Shift key in your keymap with `KC_SFTENT` (Right Shift, Enter). + +## Keycodes + +|Keycode |Description | +|-----------|-------------------------------------------| +|`KC_LSPO` |Left Shift when held, `(` when tapped | +|`KC_RSPC` |Right Shift when held, `)` when tapped | +|`KC_LCPO` |Left Control when held, `(` when tapped | +|`KC_RCPC` |Right Control when held, `)` when tapped | +|`KC_LAPO` |Left Alt when held, `(` when tapped | +|`KC_RAPC` |Right Alt when held, `)` when tapped | +|`KC_SFTENT`|Right Shift when held, Enter when tapped | + +## Caveats + +Space Cadet's functionality can conflict with the default Command functionality when both Shift keys are held at the same time. See the [Command feature](feature_command.md) for info on how to change it, or make sure that Command is disabled in your `rules.mk` with: + +```make +COMMAND_ENABLE = no +``` + +## Configuration + +By default Space Cadet assumes a US ANSI layout, but if your layout uses different keys for parentheses, you can redefine them in your `config.h`. In addition, you can redefine the modifier to send on tap, or even send no modifier at all. The new configuration defines bundle all options up into a single define of 3 key codes in this order: the `Modifier` when held or when used with other keys, the `Tap Modifer` sent when tapped (no modifier if `KC_TRNS`), finally the `Keycode` sent when tapped. Now keep in mind, mods from other keys will still apply to the `Keycode` if say `KC_RSFT` is held while tapping `KC_LSPO` key with `KC_TRNS` as the `Tap Modifer`. + +|Define |Default |Description | +|----------------|-------------------------------|---------------------------------------------------------------------------------| +|`LSPO_KEYS` |`KC_LSFT, LSPO_MOD, LSPO_KEY` |Send `KC_LSFT` when held, the mod and key defined by `LSPO_MOD` and `LSPO_KEY`. | +|`RSPC_KEYS` |`KC_RSFT, RSPC_MOD, RSPC_KEY` |Send `KC_RSFT` when held, the mod and key defined by `RSPC_MOD` and `RSPC_KEY`. | +|`LCPO_KEYS` |`KC_LCTL, KC_LSFT, KC_9` |Send `KC_LCTL` when held, the mod `KC_LSFT` with the key `KC_9` when tapped. | +|`RCPC_KEYS` |`KC_RCTL, KC_RSFT, KC_0` |Send `KC_RCTL` when held, the mod `KC_RSFT` with the key `KC_0` when tapped. | +|`LAPO_KEYS` |`KC_LALT, KC_LSFT, KC_9` |Send `KC_LALT` when held, the mod `KC_LSFT` with the key `KC_9` when tapped. | +|`RAPC_KEYS` |`KC_RALT, KC_RSFT, KC_0` |Send `KC_RALT` when held, the mod `KC_RSFT` with the key `KC_0` when tapped. | +|`SFTENT_KEYS` |`KC_RSFT, KC_TRNS, SFTENT_KEY` |Send `KC_RSFT` when held, no mod with the key `SFTENT_KEY` when tapped. | +|`SPACE_CADET_MODIFIER_CARRYOVER` |*Not defined* |Store current modifiers before the hold mod is pressed and use them with the tap mod and keycode. Useful for when you frequently release a modifier before triggering Space Cadet. | + + +## Obsolete Configuration + +These defines are used in the above defines internally to support backwards compatibility, so you may continue to use them, however the above defines open up a larger range of flexibility than before. As an example, say you want to not send any modifier when you tap just `KC_LSPO`, with the old defines you had an all or nothing choice of using the `DISABLE_SPACE_CADET_MODIFIER` define. Now you can define that key as: `#define LSPO_KEYS KC_LSFT, KC_TRNS, KC_9`. This tells the system to set Left Shift if held or used with other keys, then on tap send no modifier (transparent) with the `KC_9`. + +|Define |Default |Description | +|------------------------------|-------------|------------------------------------------------------------------| +|`LSPO_KEY` |`KC_9` |The keycode to send when Left Shift is tapped | +|`RSPC_KEY` |`KC_0` |The keycode to send when Right Shift is tapped | +|`LSPO_MOD` |`KC_LSFT` |The modifier to apply to `LSPO_KEY` | +|`RSPC_MOD` |`KC_RSFT` |The modifier to apply to `RSPC_KEY` | +|`SFTENT_KEY` |`KC_ENT` |The keycode to send when the Shift key is tapped | +|`DISABLE_SPACE_CADET_MODIFIER`|*Not defined*|If defined, prevent the Space Cadet from applying a modifier | diff --git a/feature_split_keyboard.md b/feature_split_keyboard.md new file mode 100644 index 00000000000..f054f365b6f --- /dev/null +++ b/feature_split_keyboard.md @@ -0,0 +1,246 @@ +# Split Keyboard + +Many keyboards in the QMK Firmware repo are "split" keyboards. They use two controllers—one plugging into USB, and the second connected by a serial or an I2C connection over a TRRS or similar cable. + +Split keyboards can have a lot of benefits, but there is some additional work needed to get them enabled. + +QMK Firmware has a generic implementation that is usable by any board, as well as numerous board specific implementations. + +For this, we will mostly be talking about the generic implementation used by the Let's Split and other keyboards. + +!> ARM is not yet fully supported for Split Keyboards and has many limitations. Progress is being made, but we have not yet reached 100% feature parity. + + +## Compatibility Overview + +| Transport | AVR | ARM | +|------------------------------|--------------------|--------------------| +| ['serial'](serial_driver.md) | :heavy_check_mark: | :white_check_mark: 1 | +| I2C | :heavy_check_mark: | | + +Notes: + +1. Both hardware and software limitations are detailed within the [driver documentation](serial_driver.md). + +## Hardware Configuration + +This assumes that you're using two Pro Micro-compatible controllers, and are using TRRS jacks to connect to two halves. + +### Required Hardware + +Apart from diodes and key switches for the keyboard matrix in each half, you will need 2x TRRS sockets and 1x TRRS cable. + +Alternatively, you can use any sort of cable and socket that has at least 3 wires. + +If you want to use I2C to communicate between halves, you will need a cable with at least 4 wires and 2x 4.7kΩ pull-up resistors. + +#### Considerations + +The most commonly used connection is a TRRS cable and jacks. These provide 4 wires, making them very useful for split keyboards, and are easy to find. + +However, since one of the wires carries VCC, this means that the boards are not hot pluggable. You should always disconnect the board from USB before unplugging and plugging in TRRS cables, or you can short the controller, or worse. + +Another option is to use phone cables (as in, old school RJ-11/RJ-14 cables). Make sure that you use one that actually supports 4 wires/lanes. + +However, USB cables, SATA cables, and even just 4 wires have been known to be used for communication between the controllers. + +!> Using USB cables for communication between the controllers works just fine, but the connector could be mistaken for a normal USB connection and potentially short out the keyboard, depending on how it's wired. For this reason, they are not recommended for connecting split keyboards. + +### Serial Wiring + +The 3 wires of the TRS/TRRS cable need to connect GND, VCC, and D0/D1/D2/D3 (aka PD0/PD1/PD2/PD3) between the two Pro Micros. + +?> Note that the pin used here is actually set by `SOFT_SERIAL_PIN` below. + +sk-pd0-connection-mono +sk-pd2-connection-mono + +### I2C Wiring + +The 4 wires of the TRRS cable need to connect GND, VCC, and SCL and SDA (aka PD0/pin 3 and PD1/pin 2, respectively) between the two Pro Micros. + +The pull-up resistors may be placed on either half. If you wish to use the halves independently, it is also possible to use 4 resistors and have the pull-ups in both halves. + +sk-i2c-connection-mono + +## Firmware Configuration + +To enable the split keyboard feature, add the following to your `rules.mk`: + +```make +SPLIT_KEYBOARD = yes +``` + +If you're using a custom transport (communication method), then you will also need to add: + +```make +SPLIT_TRANSPORT = custom +``` + +### Setting Handedness + +By default, the firmware does not know which side is which; it needs some help to determine that. There are several ways to do this, listed in order of precedence. + +#### Handedness by Pin + +You can configure the firmware to read a pin on the controller to determine handedness. To do this, add the following to your `config.h` file: + +```c +#define SPLIT_HAND_PIN B7 +``` + +This will read the specified pin. If it's high, then the controller assumes it is the left hand, and if it's low, it's assumed to be the right side. + +#### Handedness by Matrix Pin + +You can configure the firmware to read key matrix pins on the controller to determine handedness. To do this, add the following to your `config.h` file: + +```c +#define SPLIT_HAND_MATRIX_GRID D0, F1 +``` + +The first pin is the output pin and the second is the input pin. + +Some keyboards have unused intersections in the key matrix. This setting uses one of these unused intersections to determine the handness. + +Normally, when a diode is connected to an intersection, it is judged to be left. If you add the following definition, it will be judged to be right. + +```c +#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT +``` + +#### Handedness by EEPROM + +This method sets the keyboard's handedness by setting a flag in the persistent storage (`EEPROM`). This is checked when the controller first starts up, and determines what half the keyboard is, and how to orient the keyboard layout. + + +To enable this method, add the following to your `config.h` file: + +```c +#define EE_HANDS +``` + +However, you'll have to flash the EEPROM files for the correct hand to each controller. You can do this manually, or there are targets for avrdude and dfu to do this, while flashing the firmware: + +* `:avrdude-split-left` +* `:avrdude-split-right` +* `:dfu-split-left` +* `:dfu-split-right` +* `:dfu-util-split-left` +* `:dfu-util-split-right` + +This setting is not changed when re-initializing the EEPROM using the `EEP_RST` key, or using the `eeconfig_init()` function. However, if you reset the EEPROM outside of the firmware's built in options (such as flashing a file that overwrites the `EEPROM`, like how the [QMK Toolbox]()'s "Reset EEPROM" button works), you'll need to re-flash the controller with the `EEPROM` files. + +You can find the `EEPROM` files in the QMK firmware repo, [here](https://github.com/qmk/qmk_firmware/tree/master/quantum/split_common). + +#### Handedness by `#define` + +You can set the handedness at compile time. This is done by adding the following to your `config.h` file: + +```c +#define MASTER_RIGHT +``` + +or + +```c +#define MASTER_LEFT +``` + +If neither are defined, the handedness defaults to `MASTER_LEFT`. + + +### Communication Options + +Because not every split keyboard is identical, there are a number of additional options that can be configured in your `config.h` file. + +```c +#define USE_I2C +``` + +This enables I2C support for split keyboards. This isn't strictly for communication, but can be used for OLED or other I2C-based devices. + +```c +#define SOFT_SERIAL_PIN D0 +``` + +This sets the pin to be used for serial communication. If you're not using serial, you shouldn't need to define this. + +However, if you are using serial and I2C on the board, you will need to set this, and to something other than D0 and D1 (as these are used for I2C communication). + +```c +#define SELECT_SOFT_SERIAL_SPEED {#}` +``` + +If you're having issues with serial communication, you can change this value, as it controls the communication speed for serial. The default is 1, and the possible values are: + +* **`0`**: about 189kbps (Experimental only) +* **`1`**: about 137kbps (default) +* **`2`**: about 75kbps +* **`3`**: about 39kbps +* **`4`**: about 26kbps +* **`5`**: about 20kbps + +### Hardware Configuration Options + +There are some settings that you may need to configure, based on how the hardware is set up. + +```c +#define MATRIX_ROW_PINS_RIGHT { } +#define MATRIX_COL_PINS_RIGHT { } +``` + +This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). + +```c +#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } } +``` + +This allows you to specify a different set of direct pins for the right side. + +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + +This allows you to specify a different set of encoder pins for the right side. + +```c +#define RGBLIGHT_SPLIT +``` + +This option enables synchronization of the RGB Light modes between the controllers of the split keyboard. This is for keyboards that have RGB LEDs that are directly wired to the controller (that is, they are not using the "extra data" option on the TRRS cable). + +```c +#define RGBLED_SPLIT { 6, 6 } +``` + +This sets how many LEDs are directly connected to each controller. The first number is the left side, and the second number is the right side. + +?> This setting implies that `RGBLIGHT_SPLIT` is enabled, and will forcibly enable it, if it's not. + + +```c +#define SPLIT_USB_DETECT +``` +This option changes the startup behavior to detect an active USB connection when delegating master/slave. If this operation times out, then the half is assume to be a slave. This is the default behavior for ARM, and required for AVR Teensy boards (due to hardware limitations). + +?> This setting will stop the ability to demo using battery packs. + +```c +#define SPLIT_USB_TIMEOUT 2000 +``` +This sets the maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`. + +```c +#define SPLIT_USB_TIMEOUT_POLL 10 +``` +This sets the poll frequency when detecting master/slave when using `SPLIT_USB_DETECT` + +## Additional Resources + +Nicinabox has a [very nice and detailed guide](https://github.com/nicinabox/lets-split-guide) for the Let's Split keyboard, that covers most everything you need to know, including troubleshooting information. + +However, the RGB Light section is out of date, as it was written long before the RGB Split code was added to QMK Firmware. Instead, wire each strip up directly to the controller. + + diff --git a/feature_stenography.md b/feature_stenography.md new file mode 100644 index 00000000000..148d61b0442 --- /dev/null +++ b/feature_stenography.md @@ -0,0 +1,132 @@ +# Stenography in QMK :id=stenography-in-qmk + +[Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy). + +The [Open Steno Project](http://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports + +## Plover with QWERTY Keyboard :id=plover-with-qwerty-keyboard + +Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar. + +To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys. + +## Plover with Steno Protocol :id=plover-with-steno-protocol + +Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`. + +When QMK speaks to Plover over a steno protocol Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover. + +In this mode Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard. By default QMK will speak the TX Bolt protocol but can be switched to GeminiPR; the last protocol used is stored in non-volatile memory so QMK will use the same protocol on restart. + +> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time. + +### TX Bolt :id=tx-bolt + +TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets. + +### GeminiPR :id=geminipr + +GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories. + +## Configuring QMK for Steno :id=configuring-qmk-for-steno + +Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them. + +```makefile +STENO_ENABLE = yes +MOUSEKEY_ENABLE = no +``` + +In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function: + +```c +void matrix_init_user() { + steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT +} +``` + +Once you have your keyboard flashed launch Plover. Click the 'Configure...' button. In the 'Machine' tab select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control). + +On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno! + +## Learning Stenography :id=learning-stenography + +* [Learn Plover!](https://sites.google.com/site/learnplover/) +* [QWERTY Steno](http://qwertysteno.com/Home/) +* [Steno Jig](https://joshuagrams.github.io/steno-jig/) +* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki + +## Interfacing with the code :id=interfacing-with-the-code + +The steno code has three interceptable hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things. + +```c +bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]); +``` + +This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen. + +```c +bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } +``` + +This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values. + +```c +bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed); +``` + +This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys. + + +## Keycode Reference :id=keycode-reference + +As defined in `keymap_steno.h`. + +> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both. + +|GeminiPR|TX Bolt|Steno Key| +|--------|-------|-----------| +|`STN_N1`|`STN_NUM`|Number bar #1| +|`STN_N2`|`STN_NUM`|Number bar #2| +|`STN_N3`|`STN_NUM`|Number bar #3| +|`STN_N4`|`STN_NUM`|Number bar #4| +|`STN_N5`|`STN_NUM`|Number bar #5| +|`STN_N6`|`STN_NUM`|Number bar #6| +|`STN_N7`|`STN_NUM`|Number bar #7| +|`STN_N8`|`STN_NUM`|Number bar #8| +|`STN_N9`|`STN_NUM`|Number bar #9| +|`STN_NA`|`STN_NUM`|Number bar #A| +|`STN_NB`|`STN_NUM`|Number bar #B| +|`STN_NC`|`STN_NUM`|Number bar #C| +|`STN_S1`|`STN_SL`| `S-` upper| +|`STN_S2`|`STN_SL`| `S-` lower| +|`STN_TL`|`STN_TL`| `T-`| +|`STN_KL`|`STN_KL`| `K-`| +|`STN_PL`|`STN_PL`| `P-`| +|`STN_WL`|`STN_WL`| `W-`| +|`STN_HL`|`STN_HL`| `H-`| +|`STN_RL`|`STN_RL`| `R-`| +|`STN_A`|`STN_A`| `A` vowel| +|`STN_O`|`STN_O`| `O` vowel| +|`STN_ST1`|`STN_STR`| `*` upper-left | +|`STN_ST2`|`STN_STR`| `*` lower-left| +|`STN_ST3`|`STN_STR`| `*` upper-right| +|`STN_ST4`|`STN_STR`| `*` lower-right| +|`STN_E`|`STN_E`| `E` vowel| +|`STN_U`|`STN_U`| `U` vowel| +|`STN_FR`|`STN_FR`| `-F`| +|`STN_PR`|`STN_PR`| `-P`| +|`STN_RR`|`STN_RR`| `-R`| +|`STN_BR`|`STN_BR`| `-B`| +|`STN_LR`|`STN_LR`| `-L`| +|`STN_GR`|`STN_GR`| `-G`| +|`STN_TR`|`STN_TR`| `-T`| +|`STN_SR`|`STN_SR`| `-S`| +|`STN_DR`|`STN_DR`| `-D`| +|`STN_ZR`|`STN_ZR`| `-Z`| +|`STN_FN`|| (GeminiPR only)| +|`STN_RES1`||(GeminiPR only)| +|`STN_RES2`||(GeminiPR only)| +|`STN_PWR`||(GeminiPR only)| + diff --git a/feature_swap_hands.md b/feature_swap_hands.md new file mode 100644 index 00000000000..009477d2033 --- /dev/null +++ b/feature_swap_hands.md @@ -0,0 +1,31 @@ +# Swap-Hands Action + +The swap-hands action allows support for one-handed typing without requiring a separate layer. Set `SWAP_HANDS_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command key is pressed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd` + +## Configuration + +The configuration table is a simple 2-dimensional array to map from column/row to new column/row. Example `hand_swap_config` for Planck: + +```C +const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { + {{11, 0}, {10, 0}, {9, 0}, {8, 0}, {7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, + {{11, 1}, {10, 1}, {9, 1}, {8, 1}, {7, 1}, {6, 1}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, + {{11, 2}, {10, 2}, {9, 2}, {8, 2}, {7, 2}, {6, 2}, {5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, + {{11, 3}, {10, 3}, {9, 3}, {8, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, +}; +``` + +Note that the array indices are reversed same as the matrix and the values are of type `keypos_t` which is `{col, row}` and all values are zero-based. In the example above, `hand_swap_config[2][4]` (third row, fifth column) would return `{7, 2}` (third row, eighth column). Yes, this is confusing. + +## Swap Keycodes + +|Key |Description | +|-----------|-------------------------------------------------------------------------| +|`SH_T(key)`|Sends `key` with a tap; momentary swap when held. | +|`SH_ON` |Turns on swapping and leaves it on. | +|`SH_OFF` |Turn off swapping and leaves it off. Good for returning to a known state.| +|`SH_MON` |Swaps hands when pressed, returns to normal when released (momentary). | +|`SH_MOFF` |Momentarily turns off swap. | +|`SH_TG` |Toggles swap on and off with every key press. | +|`SH_TT` |Toggles with a tap; momentary when held. | +|`SH_OS` |One shot swap hands: toggles while pressed or until next key press. | diff --git a/feature_tap_dance.md b/feature_tap_dance.md new file mode 100644 index 00000000000..d2da39ad2b7 --- /dev/null +++ b/feature_tap_dance.md @@ -0,0 +1,512 @@ +# Tap Dance: A Single Key Can Do 3, 5, or 100 Different Things + +## Introduction :id=introduction + +Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a colon. Hit it three times, and your keyboard's LEDs do a wild dance. That's just one example of what Tap Dance can do. It's one of the nicest community-contributed features in the firmware, conceived and created by [algernon](https://github.com/algernon) in [#451](https://github.com/qmk/qmk_firmware/pull/451). Here's how algernon describes the feature: + +With this feature one can specify keys that behave differently, based on the amount of times they have been tapped, and when interrupted, they get handled before the interrupter. + +## How to Use Tap Dance :id=how-to-use + +First, you will need `TAP_DANCE_ENABLE = yes` in your `rules.mk`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. + +Optionally, you might want to set a custom `TAPPING_TERM` time by adding something like this in you `config.h`: + +```c +#define TAPPING_TERM 175 +``` + +The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. + +Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that takes a number which will later be used as an index into the `tap_dance_actions` array. + +After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options: + +* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held. +* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode). + * This is the same as `ACTION_TAP_DANCE_DUAL_ROLE`, but renamed to something that is clearer about its functionality. Both names will work. +* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode). +* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action. +* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets. +* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`. + * This is deprecated in favor of the Per Key Tapping Term functionality, as outlined [here](custom_quantum_functions.md#Custom_Tapping_Term). You'd want to check for the specific `TD()` macro that you want to use (such as `TD(TD_ESC_CAPS)`) instead of using this specific Tap Dance function. + + +The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise. + +!> Keep in mind that only [basic keycodes](keycodes_basic.md) are supported here. Custom keycodes are not supported. + +Similar to the first option, the second option is good for simple layer-switching cases. + +For more complicated cases, use the third or fourth options (examples of each are listed below). + +Finally, the fifth option is particularly useful if your non-Tap-Dance keys start behaving weirdly after adding the code for your Tap Dance keys. The likely problem is that you changed the `TAPPING_TERM` time to make your Tap Dance keys easier for you to use, and that this has changed the way your other keys handle interrupts. + +## Implementation Details :id=implementation + +Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works! + +The main entry point is `process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and reset the timer. + +This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness. + +Our next stop is `matrix_scan_tap_dance()`. This handles the timeout of tap-dance keys. + +For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros. + +## Examples :id=examples + +### Simple Example :id=simple-example + +Here's a simple example for a single definition: + +1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes` +2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200` +3. In your `keymap.c` file, define the variables and definitions, then add to your keymap: + +```c +// Tap Dance declarations +enum { + TD_ESC_CAPS, +}; + +// Tap Dance definitions +qk_tap_dance_action_t tap_dance_actions[] = { + // Tap once for Escape, twice for Caps Lock + [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), +}; + +// Add tap dance item in place of a key code +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + // ... + TD(TD_ESC_CAPS) + // ... +}; +``` + +### Complex Examples :id=complex-examples + +This section details several complex tap dance examples. +All the enums used in the examples are declared like this: + +```c +// Enums defined for all examples: +enum { + CT_SE, + CT_CLN, + CT_EGG, + CT_FLSH, + X_TAP_DANCE +}; +``` + +#### Example 1: Send `:` on Single Tap, `;` on Double Tap :id=example-1 + +```c +void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + register_code16(KC_COLN); + } else { + register_code(KC_SCLN); + } +} + +void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + unregister_code16(KC_COLN); + } else { + unregister_code(KC_SCLN); + } +} + +// All tap dance functions would go here. Only showing this one. +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), +}; +``` + +#### Example 2: Send "Safety Dance!" After 100 Taps :id=example-2 + +```c +void dance_egg(qk_tap_dance_state_t *state, void *user_data) { + if (state->count >= 100) { + SEND_STRING("Safety dance!"); + reset_tap_dance(state); + } +} + +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), +}; +``` + +#### Example 3: Turn LED Lights On Then Off, One at a Time :id=example-3 + +```c +// On each tap, light up one LED, from right to left +// On the fourth tap, turn them off from right to left +void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { + switch (state->count) { + case 1: + ergodox_right_led_3_on(); + break; + case 2: + ergodox_right_led_2_on(); + break; + case 3: + ergodox_right_led_1_on(); + break; + case 4: + ergodox_right_led_3_off(); + wait_ms(50); + ergodox_right_led_2_off(); + wait_ms(50); + ergodox_right_led_1_off(); + } +} + +// On the fourth tap, set the keyboard on flash state +void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) { + if (state->count >= 4) { + reset_keyboard(); + } +} + +// If the flash state didn't happen, then turn off LEDs, left to right +void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { + ergodox_right_led_1_off(); + wait_ms(50); + ergodox_right_led_2_off(); + wait_ms(50); + ergodox_right_led_3_off(); +} + +// All tap dances now put together. Example 3 is "CT_FLASH" +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT), + [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), + [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), + [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset) +}; +``` + +#### Example 4: 'Quad Function Tap-Dance' :id=example-4 + +By [DanielGGordon](https://github.com/danielggordon) + +Allow one key to have 4 (or more) functions, depending on number of presses, and if the key is held or tapped. +Below is a specific example: +* Tap = Send `x` +* Hold = Send `Control` +* Double Tap = Send `Escape` +* Double Tap and Hold = Send `Alt` + +You will need a few things that can be used for 'Quad Function Tap-Dance'. + +You'll need to add these to the top of your `keymap.c` file, before your keymap. + +```c +typedef struct { + bool is_press_action; + uint8_t state; +} tap; + +enum { + SINGLE_TAP = 1, + SINGLE_HOLD, + DOUBLE_TAP, + DOUBLE_HOLD, + DOUBLE_SINGLE_TAP, // Send two single taps + TRIPLE_TAP, + TRIPLE_HOLD +}; + +// Tap dance enums +enum { + X_CTL, + SOME_OTHER_DANCE +}; + +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// For the x tap dance. Put it here so it can be used in any keymap +void x_finished(qk_tap_dance_state_t *state, void *user_data); +void x_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +Now, at the bottom of your `keymap.c` file, you'll need to add the following: + +```c +/* Return an integer that corresponds to what kind of tap dance should be executed. + * + * How to figure out tap dance state: interrupted and pressed. + * + * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit + * under the tapping term. This is typically indicitive that you are trying to "tap" the key. + * + * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term + * has ended, but the key is still being pressed down. This generally means the key is being "held". + * + * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold" + * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters. + * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters. + * + * Good places to put an advanced tap dance: + * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon + * + * Criteria for "good placement" of a tap dance key: + * Not a key that is hit frequently in a sentence + * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or + * in a web form. So 'tab' would be a poor choice for a tap dance. + * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the + * letter 'p', the word 'pepper' would be quite frustating to type. + * + * For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested + * + */ +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (state->interrupted || !state->pressed) return SINGLE_TAP; + // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'. + else return SINGLE_HOLD; + } else if (state->count == 2) { + // DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap + // action when hitting 'pp'. Suggested use case for this return value is when you want to send two + // keystrokes of the key, and not the 'double tap' action/macro. + if (state->interrupted) return DOUBLE_SINGLE_TAP; + else if (state->pressed) return DOUBLE_HOLD; + else return DOUBLE_TAP; + } + + // Assumes no one is trying to type the same letter three times (at least not quickly). + // If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add + // an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP' + if (state->count == 3) { + if (state->interrupted || !state->pressed) return TRIPLE_TAP; + else return TRIPLE_HOLD; + } else return 8; // Magic number. At some point this method will expand to work for more presses +} + +// Create an instance of 'tap' for the 'x' tap dance. +static tap xtap_state = { + .is_press_action = true, + .state = 0 +}; + +void x_finished(qk_tap_dance_state_t *state, void *user_data) { + xtap_state.state = cur_dance(state); + switch (xtap_state.state) { + case SINGLE_TAP: register_code(KC_X); break; + case SINGLE_HOLD: register_code(KC_LCTRL); break; + case DOUBLE_TAP: register_code(KC_ESC); break; + case DOUBLE_HOLD: register_code(KC_LALT); break; + // Last case is for fast typing. Assuming your key is `f`: + // For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`. + // In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms. + case DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X); + } +} + +void x_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (xtap_state.state) { + case SINGLE_TAP: unregister_code(KC_X); break; + case SINGLE_HOLD: unregister_code(KC_LCTRL); break; + case DOUBLE_TAP: unregister_code(KC_ESC); break; + case DOUBLE_HOLD: unregister_code(KC_LALT); + case DOUBLE_SINGLE_TAP: unregister_code(KC_X); + } + xtap_state.state = 0; +} + +qk_tap_dance_action_t tap_dance_actions[] = { + [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset) +}; +``` + +And then simply use `TD(X_CTL)` anywhere in your keymap. + +If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace. + +> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`). + +#### Example 5: Using tap dance for advanced mod-tap and layer-tap keys :id=example-5 + +Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`. + +Below your layers and custom keycodes, add the following: + +```c +// Tap Dance keycodes +enum td_keycodes { + ALT_LP // Our example key: `LALT` when held, `(` when tapped. Add additional keycodes for each tapdance. +}; + +// Define a type containing as many tapdance states as you need +typedef enum { + SINGLE_TAP, + SINGLE_HOLD, + DOUBLE_SINGLE_TAP +} td_state_t; + +// Create a global instance of the tapdance state type +static td_state_t td_state; + +// Declare your tapdance functions: + +// Function to determine the current tapdance state +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// `finished` and `reset` functions for each tapdance keycode +void altlp_finished(qk_tap_dance_state_t *state, void *user_data); +void altlp_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +Below your `LAYOUT`, define each of the tapdance functions: + +```c +// Determine the tapdance state to return +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (state->interrupted || !state->pressed) return SINGLE_TAP; + else return SINGLE_HOLD; + } + + if (state->count == 2) return DOUBLE_SINGLE_TAP; + else return 3; // Any number higher than the maximum state value you return above +} + +// Handle the possible states for each tapdance keycode you define: + +void altlp_finished(qk_tap_dance_state_t *state, void *user_data) { + td_state = cur_dance(state); + switch (td_state) { + case SINGLE_TAP: + register_code16(KC_LPRN); + break; + case SINGLE_HOLD: + register_mods(MOD_BIT(KC_LALT)); // For a layer-tap key, use `layer_on(_MY_LAYER)` here + break; + case DOUBLE_SINGLE_TAP: // Allow nesting of 2 parens `((` within tapping term + tap_code16(KC_LPRN); + register_code16(KC_LPRN); + } +} + +void altlp_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (td_state) { + case SINGLE_TAP: + unregister_code16(KC_LPRN); + break; + case SINGLE_HOLD: + unregister_mods(MOD_BIT(KC_LALT)); // For a layer-tap key, use `layer_off(_MY_LAYER)` here + break; + case DOUBLE_SINGLE_TAP: + unregister_code16(KC_LPRN); + } +} + +// Define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions +qk_tap_dance_action_t tap_dance_actions[] = { + [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) +}; +``` + +Wrap each tapdance keycode in `TD()` when including it in your keymap, e.g. `TD(ALT_LP)`. + +#### Example 6: Using tap dance for momentary-layer-switch and layer-toggle keys :id=example-6 + +Tap Dance can be used to mimic MO(layer) and TG(layer) functionality. For this example, we will set up a key to function as `KC_QUOT` on single-tap, as `MO(_MY_LAYER)` on single-hold, and `TG(_MY_LAYER)` on double-tap. + +The first step is to include the following code towards the beginning of your `keymap.c`: + +```c +typedef struct { + bool is_press_action; + uint8_t state; +} tap; + +// Define a type for as many tap dance states as you need +enum { + SINGLE_TAP = 1, + SINGLE_HOLD, + DOUBLE_TAP +}; + +enum { + QUOT_LAYR, // Our custom tap dance key; add any other tap dance keys to this enum +}; + +// Declare the functions to be used with your tap dance key(s) + +// Function associated with all tap dances +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// Functions associated with individual tap dances +void ql_finished(qk_tap_dance_state_t *state, void *user_data); +void ql_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +Towards the bottom of your `keymap.c`, include the following code: + +```c +// Determine the current tap dance state +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (!state->pressed) return SINGLE_TAP; + else return SINGLE_HOLD; + } else if (state->count == 2) return DOUBLE_TAP; + else return 8; +} + +// Initialize tap structure associated with example tap dance key +static tap ql_tap_state = { + .is_press_action = true, + .state = 0 +}; + +// Functions that control what our tap dance key does +void ql_finished(qk_tap_dance_state_t *state, void *user_data) { + ql_tap_state.state = cur_dance(state); + switch (ql_tap_state.state) { + case SINGLE_TAP: + tap_code(KC_QUOT); + break; + case SINGLE_HOLD: + layer_on(_MY_LAYER); + break; + case DOUBLE_TAP: + // Check to see if the layer is already set + if (layer_state_is(_MY_LAYER)) { + // If already set, then switch it off + layer_off(_MY_LAYER); + } else { + // If not already set, then switch the layer on + layer_on(_MY_LAYER); + } + break; + } +} + +void ql_reset(qk_tap_dance_state_t *state, void *user_data) { + // If the key was held down and now is released then switch off the layer + if (ql_tap_state.state == SINGLE_HOLD) { + layer_off(_MY_LAYER); + } + ql_tap_state.state = 0; +} + +// Associate our tap dance key with its functionality +qk_tap_dance_action_t tap_dance_actions[] = { + [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275) +}; +``` + +The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active. + +The use of `cur_dance()` and `ql_tap_state` mirrors the above examples. + +The `case:SINGLE_TAP` in `ql_finished` is similar to the above examples. The `SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`. + +`tap_dance_actions[]` works similar to the above examples. Note that I used `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` instead of `ACTION_TAP_DANCE_FN_ADVANCED()`. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here. + +Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`. diff --git a/feature_terminal.md b/feature_terminal.md new file mode 100644 index 00000000000..f8506221654 --- /dev/null +++ b/feature_terminal.md @@ -0,0 +1,107 @@ +# Terminal + +> This feature is currently *huge*, and should probably only be put on boards with a lot of memory, or for fun. + +The terminal feature is a command-line-like interface designed to communicate through a text editor with keystrokes. It's beneficial to turn off auto-indent features in your editor. + +To enable, stick this in your `rules.mk` or `Makefile`: + + TERMINAL_ENABLE = yes + +And use the `TERM_ON` and `TERM_OFF` keycodes to turn it on or off. + +When enabled, a `> ` prompt will appear, where you'll be able to type, backspace (a bell will ding if you reach the beginning and audio is enabled), and hit enter to send the command. Arrow keys are currently disabled so it doesn't get confused. Moving your cursor around with the mouse is discouraged. + +`#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page. + +Pressing "up" and "down" will allow you to cycle through the past 5 commands entered. + +## Future Ideas + +* Keyboard/user-extensible commands +* Smaller footprint +* Arrow key support +* Command history - Done +* SD card support +* LCD support for buffer display +* Keycode -> name string LUT +* Layer status +* *Analog/digital port read/write* +* RGB mode stuff +* Macro definitions +* EEPROM read/write +* Audio control + +## Current Commands + +### `about` + +Prints out the current version of QMK with a build date: + +``` +> about +QMK Firmware + v0.5.115-7-g80ed73-dirty + Built: 2017-08-29-20:24:44 +``` + + +### `print-buffer` + +Outputs the last 5 commands entered + +``` +> print-buffer +0. print-buffer +1. help +2. about +3. keymap 0 +4. help +5. flush-buffer +``` + +### `flush-buffer` + +Clears command buffer +``` +> flush-buffer +Buffer cleared! +``` + + +### `help` + + +Prints out the available commands: + +``` +> help +commands available: + about help keycode keymap exit print-buffer flush-buffer +``` + +### `keycode ` + +Prints out the keycode value of a certain layer, row, and column: + +``` +> keycode 0 1 0 +0x29 (41) +``` + +### `keymap ` + +Prints out the entire keymap for a certain layer + +``` +> keymap 0 +0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a, +0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034, +0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028, +0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f, +> +``` + +### `exit` + +Exits the terminal - same as `TERM_OFF`. diff --git a/feature_thermal_printer.md b/feature_thermal_printer.md new file mode 100644 index 00000000000..3f496646d42 --- /dev/null +++ b/feature_thermal_printer.md @@ -0,0 +1,10 @@ +# Thermal Printer + + + +## Thermal Printer Keycodes + +|Key |Description | +|-----------|----------------------------------------| +|`PRINT_ON` |Start printing everything the user types| +|`PRINT_OFF`|Stop printing everything the user types | diff --git a/feature_unicode.md b/feature_unicode.md new file mode 100644 index 00000000000..02a7bea5dab --- /dev/null +++ b/feature_unicode.md @@ -0,0 +1,272 @@ +# Unicode Support + +Unicode characters can be input straight from your keyboard! There are some limitations, however. + +In order to enable Unicode support on your keyboard, you will need to do the following: + +1. Choose one of three supported Unicode implementations: [Basic Unicode](#basic-unicode), [Unicode Map](#unicode-map), [UCIS](#ucis). +2. Find which [input mode](#input-modes) is the best match for your operating system and setup. +3. [Set](#setting-the-input-mode) the appropriate input mode (or modes) in your configuration. +4. Add Unicode keycodes to your keymap. + + +## 1. Methods :id=methods + +QMK supports three different methods for enabling Unicode input and adding Unicode characters to your keymap. Each has its pros and cons in terms of flexibility and ease of use. Choose the one that best fits your use case. + +The Basic method should be enough for most users. However, if you need a wider range of supported characters (including emoji, rare symbols etc.), you should use Unicode Map. + +
+ +### 1.1. Basic Unicode :id=basic-unicode + +The easiest to use method, albeit somewhat limited. It stores Unicode characters as keycodes in the keymap itself, so it only supports code points up to `0x7FFF`. This covers characters for most modern languages (including East Asian), as well as symbols, but it doesn't cover emoji. + +Add the following to your `rules.mk`: + +```make +UNICODE_ENABLE = yes +``` + +Then add `UC(c)` keycodes to your keymap, where _c_ is the code point of the desired character (preferably in hexadecimal, up to 4 digits long). For example, `UC(0x40B)` will output [Ћ](https://unicode-table.com/en/040B/), and `UC(0x30C4)` will output [ツ](https://unicode-table.com/en/30C4). + +
+ +### 1.2. Unicode Map :id=unicode-map + +In addition to standard character ranges, this method also covers emoji, ancient scripts, rare symbols etc. In fact, all possible code points (up to `0x10FFFF`) are supported. Here, Unicode characters are stored in a separate mapping table. You need to maintain a `unicode_map` array in your keymap file, which may contain at most 16384 entries. + +Add the following to your `rules.mk`: + +```make +UNICODEMAP_ENABLE = yes +``` + +Then add `X(i)` keycodes to your keymap, where _i_ is the desired character's index in the mapping table. This can be a numeric value, but it's recommended to keep the indices in an enum and access them by name. + +```c +enum unicode_names { + BANG, + IRONY, + SNEK +}; + +const uint32_t PROGMEM unicode_map[] = { + [BANG] = 0x203D, // ‽ + [IRONY] = 0x2E2E, // ⸮ + [SNEK] = 0x1F40D, // 🐍 +}; +``` + +Then you can use `X(BANG)`, `X(SNEK)` etc. in your keymap. + +#### Lower and Upper Case + +Characters often come in lower and upper case pairs, such as å and Å. To make inputting these characters easier, you can use `XP(i, j)` in your keymap, where _i_ and _j_ are the mapping table indices of the lower and upper case character, respectively. If you're holding down Shift or have Caps Lock turned on when you press the key, the second (upper case) character will be inserted; otherwise, the first (lower case) version will appear. + +This is most useful when creating a keymap for an international layout with special characters. Instead of having to put the lower and upper case versions of a character on separate keys, you can have them both on the same key by using `XP()`. This helps blend Unicode keys in with regular alphas. + +Due to keycode size constraints, _i_ and _j_ can each only refer to one of the first 128 characters in your `unicode_map`. In other words, 0 ≤ _i_ ≤ 127 and 0 ≤ _j_ ≤ 127. This is enough for most use cases, but if you'd like to customize the index calculation, you can override the [`unicodemap_index()`](https://github.com/qmk/qmk_firmware/blob/71f640d47ee12c862c798e1f56392853c7b1c1a8/quantum/process_keycode/process_unicodemap.c#L36) function. This also allows you to, say, check Ctrl instead of Shift/Caps. + +
+ +### 1.3. UCIS :id=ucis + +This method also supports all possible code points. As with the Unicode Map method, you need to maintain a mapping table in your keymap file. However, there are no built-in keycodes for this feature — you have to create a custom keycode or function that invokes this functionality. + +Add the following to your `rules.mk`: + +```make +UCIS_ENABLE = yes +``` + +Then define a table like this in your keymap file: + +```c +const qk_ucis_symbol_t ucis_symbol_table[] = UCIS_TABLE( + UCIS_SYM("poop", 0x1F4A9), // 💩 + UCIS_SYM("rofl", 0x1F923), // 🤣 + UCIS_SYM("cuba", 0x1F1E8, 0x1F1FA), // 🇨🇺 + UCIS_SYM("look", 0x0CA0, 0x005F, 0x0CA0), // ಠ_ಠ +); +``` + +By default, each table entry may be up to 3 code points long. This number can be changed by adding `#define UCIS_MAX_CODE_POINTS n` to your `config.h` file. + +To use UCIS input, call `qk_ucis_start()`. Then, type the mnemonic for the character (such as "rofl") and hit Space, Enter or Esc. QMK should erase the "rofl" text and insert the laughing emoji. + +#### Customization + +There are several functions that you can define in your keymap to customize the functionality of this feature. + +* `void qk_ucis_start_user(void)` – This runs when you call the "start" function, and can be used to provide feedback. By default, it types out a keyboard emoji. +* `void qk_ucis_success(uint8_t symbol_index)` – This runs when the input has matched something and has completed. By default, it doesn't do anything. +* `void qk_ucis_symbol_fallback (void)` – This runs when the input doesn't match anything. By default, it falls back to trying that input as a Unicode code. + +You can find the default implementations of these functions in [`process_ucis.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_ucis.c). + + +## 2. Input Modes :id=input-modes + +Unicode input in QMK works by inputting a sequence of characters to the OS, sort of like a macro. Unfortunately, the way this is done differs for each platform. Specifically, each platform requires a different combination of keys to trigger Unicode input. Therefore, a corresponding input mode has to be set in QMK. + +The following input modes are available: + +* **`UC_MAC`**: macOS built-in Unicode hex input. Supports code points up to `0x10FFFF` (all possible code points). + + To enable, go to _System Preferences > Keyboard > Input Sources_, add _Unicode Hex Input_ to the list (it's under _Other_), then activate it from the input dropdown in the Menu Bar. + By default, this mode uses the left Option key (`KC_LALT`) for Unicode input, but this can be changed by defining [`UNICODE_KEY_MAC`](#input-key-configuration) with a different keycode. + + !> Using the _Unicode Hex Input_ input source may disable some Option-based shortcuts, such as Option+Left and Option+Right. + + !> `UC_OSX` is a deprecated alias of `UC_MAC` that will be removed in future versions of QMK. All new keymaps should use `UC_MAC`. + +* **`UC_LNX`**: Linux built-in IBus Unicode input. Supports code points up to `0x10FFFF` (all possible code points). + + Enabled by default and works almost anywhere on IBus-enabled distros. Without IBus, this mode works under GTK apps, but rarely anywhere else. + By default, this mode uses Ctrl+Shift+U (`LCTL(LSFT(KC_U))`) to start Unicode input, but this can be changed by defining [`UNICODE_KEY_LNX`](#input-key-configuration) with a different keycode. This might be required for IBus versions ≥1.5.15, where Ctrl+Shift+U behavior is consolidated into Ctrl+Shift+E. + +* **`UC_WIN`**: _(not recommended)_ Windows built-in hex numpad Unicode input. Supports code points up to `0xFFFF`. + + To enable, create a registry key under `HKEY_CURRENT_USER\Control Panel\Input Method` of type `REG_SZ` called `EnableHexNumpad` and set its value to `1`. This can be done from the Command Prompt by running `reg add "HKCU\Control Panel\Input Method" -v EnableHexNumpad -t REG_SZ -d 1` with administrator privileges. Reboot afterwards. + This mode is not recommended because of reliability and compatibility issues; use the `UC_WINC` mode instead. + +* **`UC_BSD`**: _(non implemented)_ Unicode input under BSD. Not implemented at this time. If you're a BSD user and want to help add support for it, please [open an issue on GitHub](https://github.com/qmk/qmk_firmware/issues). + +* **`UC_WINC`**: Windows Unicode input using [WinCompose](https://github.com/samhocevar/wincompose). As of v0.9.0, supports code points up to `0x10FFFF` (all possible code points). + + To enable, install the [latest release](https://github.com/samhocevar/wincompose/releases/latest). Once installed, WinCompose will automatically run on startup. This mode works reliably under all version of Windows supported by the app. + By default, this mode uses right Alt (`KC_RALT`) as the Compose key, but this can be changed in the WinCompose settings and by defining [`UNICODE_KEY_WINC`](#input-key-configuration) with a different keycode. + + +## 3. Setting the Input Mode :id=setting-the-input-mode + +To set your desired input mode, add the following define to your `config.h`: + +```c +#define UNICODE_SELECTED_MODES UC_LNX +``` + +This example sets the board's default input mode to `UC_LNX`. You can replace this with `UC_MAC`, `UC_WINC`, or any of the other modes listed [above](#input-modes). The board will automatically use the selected mode on startup, unless you manually switch to another mode (see [below](#keycodes)). + +You can also select multiple input modes, which allows you to easily cycle through them using the `UC_MOD`/`UC_RMOD` keycodes. + +```c +#define UNICODE_SELECTED_MODES UC_MAC, UC_LNX, UC_WINC +``` + +Note that the values are separated by commas. The board will remember the last used input mode and will continue using it on next power-up. You can disable this and force it to always start with the first mode in the list by adding `#define UNICODE_CYCLE_PERSIST false` to your `config.h`. + +#### Keycodes + +You can switch the input mode at any time by using the following keycodes. Adding these to your keymap allows you to quickly switch to a specific input mode, including modes not listed in `UNICODE_SELECTED_MODES`. + +|Keycode |Alias |Input Mode |Description | +|----------------------|---------|------------|-----------------------------------------------------------------------------| +|`UNICODE_MODE_FORWARD`|`UC_MOD` |Next in list|Cycle through selected modes, reverse direction when Shift is held | +|`UNICODE_MODE_REVERSE`|`UC_RMOD`|Prev in list|Cycle through selected modes in reverse, forward direction when Shift is held| +|`UNICODE_MODE_MAC` |`UC_M_MA`|`UC_MAC` |Switch to macOS input | +|`UNICODE_MODE_LNX` |`UC_M_LN`|`UC_LNX` |Switch to Linux input | +|`UNICODE_MODE_WIN` |`UC_M_WI`|`UC_WIN` |Switch to Windows input | +|`UNICODE_MODE_BSD` |`UC_M_BS`|`UC_BSD` |Switch to BSD input _(not implemented)_ | +|`UNICODE_MODE_WINC` |`UC_M_WC`|`UC_WINC` |Switch to Windows input using WinCompose | + +You can also switch the input mode by calling `set_unicode_input_mode(x)` in your code, where _x_ is one of the above input mode constants (e.g. `UC_LNX`). + +?> Using `UNICODE_SELECTED_MODES` is preferable to calling `set_unicode_input_mode()` in `matrix_init_user()` or similar functions, since it's better integrated into the Unicode system and has the added benefit of avoiding unnecessary writes to EEPROM. + +#### Audio Feedback + +If you have the [Audio feature](feature_audio.md) enabled on the board, you can set melodies to be played when you press the above keys. That way you can have some audio feedback when switching input modes. + +For instance, you can add these definitions to your `config.h` file: + +```c +#define UNICODE_SONG_MAC AUDIO_ON_SOUND +#define UNICODE_SONG_LNX UNICODE_LINUX +#define UNICODE_SONG_BSD TERMINAL_SOUND +#define UNICODE_SONG_WIN UNICODE_WINDOWS +#define UNICODE_SONG_WINC UNICODE_WINDOWS +``` + + +## Additional Customization + +Because Unicode is a large and versatile feature, there are a number of options you can customize to make it work better on your system. + +### Start and Finish Input Functions + +The functions for starting and finishing Unicode input on your platform can be overridden locally. Possible uses include customizing input mode behavior if you don't use the default keys, or adding extra visual/audio feedback to Unicode input. + +* `void unicode_input_start(void)` – This sends the initial sequence that tells your platform to enter Unicode input mode. For example, it holds the left Alt key followed by Num+ on Windows, and presses the `UNICODE_KEY_LNX` combination (default: Ctrl+Shift+U) on Linux. +* `void unicode_input_finish(void)` – This is called to exit Unicode input mode, for example by pressing Space or releasing the Alt key. + +You can find the default implementations of these functions in [`process_unicode_common.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_unicode_common.c). + +### Input Key Configuration + +You can customize the keys used to trigger Unicode input for macOS, Linux and WinCompose by adding corresponding defines to your `config.h`. The default values match the platforms' default settings, so you shouldn't need to change this unless Unicode input isn't working, or you want to use a different key (e.g. in order to free up left or right Alt). + +|Define |Type |Default |Example | +|------------------|----------|------------------|-------------------------------------------| +|`UNICODE_KEY_MAC` |`uint8_t` |`KC_LALT` |`#define UNICODE_KEY_MAC KC_RALT` | +|`UNICODE_KEY_LNX` |`uint16_t`|`LCTL(LSFT(KC_U))`|`#define UNICODE_KEY_LNX LCTL(LSFT(KC_E))`| +|`UNICODE_KEY_WINC`|`uint8_t` |`KC_RALT` |`#define UNICODE_KEY_WINC KC_RGUI` | + + +## Sending Unicode Strings + +QMK provides several functions that allow you to send Unicode input to the host programmatically: + +### `send_unicode_string()` + +This function is much like `send_string()`, but it allows you to input UTF-8 characters directly. It supports all code points, provided the selected input mode also supports it. Make sure your `keymap.c` file is formatted using UTF-8 encoding. + +```c +send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); +``` + +Example uses include sending Unicode strings when a key is pressed, as described in [Macros](feature_macros.md). + +### `send_unicode_hex_string()` + +Similar to `send_unicode_string()`, but the characters are represented by their Unicode code points, written in hexadecimal and separated by spaces. For example, the table flip above would be achieved with: + +```c +send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B"); +``` + +An easy way to convert your Unicode string to this format is to use [this site](https://r12a.github.io/app-conversion/) and take the result in the "Hex/UTF-32" section. + + +## Additional Language Support + +In `quantum/keymap_extras`, you'll see various language files — these work the same way as the ones for alternative layouts such as Colemak or BÉPO. When you include one of these language headers, you gain access to keycodes specific to that language / national layout. Such keycodes are defined by a 2-letter country/language code, followed by an underscore and a 4-letter abbreviation of the character to which the key corresponds. For example, including `keymap_french.h` and using `FR_UGRV` in your keymap will output `ù` when typed on a system with a native French AZERTY layout. + +If the primary system layout you use on your machine is different from US ANSI, using these language-specific keycodes can help your QMK keymaps better match what will actually be output on the screen. However, keep in mind that these keycodes are just aliases for the corresponding default US keycodes under the hood, and that the HID protocol used by keyboards is itself inherently based on US ANSI. + + +## International Characters on Windows + +### AutoHotkey + +The method does not require Unicode support in the keyboard itself but instead depends on [AutoHotkey](https://autohotkey.com) running in the background. + +First you need to select a modifier combination that is not in use by any of your programs. +Ctrl+Alt+Win is not used very widely and should therefore be perfect for this. +There is a macro defined for a mod-tab combo `LCAG_T`. +Add this mod-tab combo to a key on your keyboard, e.g.: `LCAG_T(KC_TAB)`. +This makes the key behave like a tab key if pressed and released immediately but changes it to the modifier if used with another key. + +In the default script of AutoHotkey you can define custom hotkeys. + + <^`) with the following structure: + +* `/users//` (added to the path automatically) + * `readme.md` (optional, recommended) + * `rules.mk` (included automatically) + * `config.h` (included automatically) + * `.h` (optional) + * `.c` (optional) + * `cool_rgb_stuff.c` (optional) + * `cool_rgb_stuff.h` (optional) + + +All this only happens when you build a keymap named ``, like this: + + make planck: + +For example, + + make planck:jack + +Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`. + +!> This `name` can be [overridden](#override-default-userspace), if needed. + +## `Rules.mk` + +The `rules.mk` is one of the two files that gets processed automatically. This is how you add additional source files (such as `.c`) will be added when compiling. + +It's highly recommended that you use `.c` as the default source file to be added. And to add it, you need to add it the SRC in `rules.mk` like this: + + SRC += .c + +Additional files may be added in the same way - it's recommended you have one named ``.c/.h to start off with, though. + +The `/users//rules.mk` file will be included in the build _after_ the `rules.mk` from your keymap. This allows you to have features in your userspace `rules.mk` that depend on individual QMK features that may or may not be available on a specific keyboard. + +For example, if you have RGB control features shared between all your keyboards that support RGB lighting, you can add support for that if the RGBLIGHT feature is enabled: +```make +ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) + # Include my fancy rgb functions source here + SRC += cool_rgb_stuff.c +endif +``` + +Alternatively, you can `define RGB_ENABLE` in your keymap's `rules.mk` and then check for the variable in your userspace's `rules.mk` like this: +```make +ifdef RGB_ENABLE + # Include my fancy rgb functions source here + SRC += cool_rgb_stuff.c +endif +``` + +### Override default userspace + +By default the userspace used will be the same as the keymap name. In some situations this isn't desirable. For instance, if you use the [layout](feature_layouts.md) feature you can't use the same name for different keymaps (e.g. ANSI and ISO). You can name your layouts `mylayout-ansi` and `mylayout-iso` and add the following line to your layout's `rules.mk`: + +``` +USER_NAME := mylayout +``` + +This is also useful if you have multiple different keyboards with different features physically present on the board (such as one with RGB Lights, and one with Audio, or different number of LEDs, or connected to a different PIN on the controller). + +## Configuration Options (`config.h`) + +Additionally, `config.h` here will be processed like the same file in your keymap folder. This is handled separately from the `.h` file. + +The reason for this, is that `.h` won't be added in time to add settings (such as `#define TAPPING_TERM 100`), and including the `` file in any `config.h` files will result in compile issues. + +!>You should use the `config.h` for [configuration options](config_options.md), and the `.h` file for user or keymap specific settings (such as the enum for layer or keycodes) + + +## Readme (`readme.md`) + +Please include authorship (your name, GitHub username, email), and optionally [a license that's GPL compatible](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses). + +You can use this as a template: +``` +Copyright @ + +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 . +``` + +You'd want to replace the year, name, email and GitHub username with your info. + +Additionally, this is a good place to document your code, if you wish to share it with others. + +## Build All Keyboards That Support a Specific Keymap + +Want to check all your keymaps build in a single command? You can run: + + make all: + +For example, + + make all:jack + +This is ideal for when you want ensure everything compiles successfully when preparing a [_Pull request_](https://github.com/qmk/qmk_firmware/pulls). + +## Examples + +For a brief example, checkout [`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/_example). +For a more complicated example, checkout [`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna)'s userspace. + + +### Customized Functions + +QMK has a bunch of [functions](custom_quantum_functions.md) that have [`_quantum`, `_kb`, and `_user` versions](custom_quantum_functions.md#a-word-on-core-vs-keyboards-vs-keymap) that you can use. You will pretty much always want to use the user version of these functions. But the problem is that if you use them in your userspace, then you don't have a version that you can use in your keymap. + +However, you can actually add support for keymap version, so that you can use it in both your userspace and your keymap! + + +For instance, let's look at the `layer_state_set_user()` function. You can enable the [Tri Layer State](ref_functions.md#olkb-tri-layers) functionality on all of your boards, while also retaining the Tri Layer functionality in your `keymap.c` files. + +In your `` file, you'd want to add this: +```c +__attribute__ ((weak)) +layer_state_t layer_state_set_keymap (layer_state_t state) { + return state; +} + +layer_state_t layer_state_set_user (layer_state_t state) { + state = update_tri_layer_state(state, 2, 3, 5); + return layer_state_set_keymap (state); +} +``` +The `__attribute__ ((weak))` part tells the compiler that this is a placeholder function that can then be replaced by a version in your `keymap.c`. That way, you don't need to add it to your `keymap.c`, but if you do, you won't get any conflicts because the function is the same name. + +The `_keymap` part here doesn't matter, it just needs to be something other than `_quantum`, `_kb`, or `_user`, since those are already in use. So you could use `layer_state_set_mine`, `layer_state_set_fn`, or anything else. + +You can see a list of this and other common functions in [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) in [`users/drashna`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna). + +### Custom Features + +Since the Userspace feature can support a staggering number of boards, you may have boards that you want to enable certain functionality for, but not for others. And you can actually create "features" that you can enable or disable in your own userspace. + +For instance, if you wanted to have a bunch of macros available, but only on certain boards (to save space), you could "hide" them being a `#ifdef MACROS_ENABLED`, and then enable it per board. To do this, add this to your rules.mk +```make +ifeq ($(strip $(MACROS_ENABLED)), yes) + OPT_DEFS += -DMACROS_ENABLED +endif +``` +The `OPT_DEFS` setting causes `MACROS_ENABLED` to be defined for your keyboards (note the `-D` in front of the name), and you could use `#ifdef MACROS_ENABLED` to check the status in your c/h files, and handle that code based on that. + +Then you add `MACROS_ENABLED = yes` to the `rules.mk` for you keymap to enable this feature and the code in your userspace. + +And in your `process_record_user` function, you'd do something like this: +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { +#ifdef MACROS_ENABLED + case MACRO1: + if (!record->event.pressed) { + SEND_STRING("This is macro 1!"); + } + break; + case MACRO2: + if (!record->event.pressed) { + SEND_STRING("This is macro 2!"); + } + break; +#endif + } + return true; +} +``` + + +### Consolidated Macros + +If you wanted to consolidate macros and other functions into your userspace for all of your keymaps, you can do that. This builds upon the [Customized Functions](#customized-functions) example above. This lets you maintain a bunch of macros that are shared between the different keyboards, and allow for keyboard specific macros, too. + +First, you'd want to go through all of your `keymap.c` files and replace `process_record_user` with `process_record_keymap` instead. This way, you can still use keyboard specific codes on those boards, and use your custom "global" keycodes as well. You'll also want to replace `SAFE_RANGE` with `NEW_SAFE_RANGE` so that you wont have any overlapping keycodes + +Then add `#include ` to all of your keymap.c files. This allows you to use these new keycodes without having to redefine them in each keymap. + +Once you've done that, you'll want to set the keycode definitions that you need to the `.h` file. For instance: +```c +#pragma once + +#include "quantum.h" +#include "action.h" +#include "version.h" + +// Define all of +enum custom_keycodes { + KC_MAKE = SAFE_RANGE, + NEW_SAFE_RANGE //use "NEW_SAFE_RANGE" for keymap specific codes +}; +``` + +Now you want to create the `.c` file, and add this content to it: + +```c +#include ".h" + +__attribute__ ((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader + if (!record->event.pressed) { + uint8_t temp_mod = get_mods(); + uint8_t temp_osm = get_oneshot_mods(); + clear_mods(); clear_oneshot_mods(); + SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP); + #ifndef FLASH_BOOTLOADER + if ((temp_mod | temp_osm) & MOD_MASK_SHIFT) + #endif + { + SEND_STRING(":flash"); + } + if ((temp_mod | temp_osm) & MOD_MASK_CTRL) { + SEND_STRING(" -j8 --output-sync"); + } + tap_code(KC_ENT); + set_mods(temp_mod); + } + break; + + } + return process_record_keymap(keycode, record); +} +``` + +For boards that may not have a shift button (such as on a macro pad), we need a way to always include the bootloader option. To do that, add the following to the `rules.mk` in your userspace folder: + +```make +ifeq ($(strip $(FLASH_BOOTLOADER)), yes) + OPT_DEFS += -DFLASH_BOOTLOADER +endif +``` + +This will add a new `KC_MAKE` keycode that can be used in any of your keymaps. And this keycode will output `make :`, making frequent compiling easier. And this will work with any keyboard and any keymap as it will output the current boards info, so that you don't have to type this out every time. + +Also, holding Shift will add the flash target (`:flash`) to the command. Holding Control will add some commands that will speed up compiling time by processing multiple files at once. + +And for the boards that lack a shift key, or that you want to always attempt the flashing part, you can add `FLASH_BOOTLOADER = yes` to the `rules.mk` of that keymap. + +?> This should flash the newly compiled firmware automatically, using the correct utility, based on the bootloader settings (or default to just generating the HEX file). However, it should be noted that this may not work on all systems. AVRDUDE doesn't work on WSL, namely. And this doesn't support BootloadHID or mdloader. diff --git a/feature_velocikey.md b/feature_velocikey.md new file mode 100644 index 00000000000..5d98410735b --- /dev/null +++ b/feature_velocikey.md @@ -0,0 +1,30 @@ +# Velocikey + +Velocikey is a feature that lets you control the speed of lighting effects (like the Rainbow Swirl effect) with the speed of your typing. The faster you type, the faster the lights will go! + +## Usage +For Velocikey to take effect, there are two steps. First, when compiling your keyboard, you'll need to set `VELOCIKEY_ENABLE=yes` in `rules.mk`, e.g.: + +``` +BOOTMAGIC_ENABLE = no +MOUSEKEY_ENABLE = no +STENO_ENABLE = no +EXTRAKEY_ENABLE = yes +VELOCIKEY_ENABLE = yes +``` + +Then, while using your keyboard, you need to also turn it on with the VLK_TOG keycode, which toggles the feature on and off. + +The following light effects will all be controlled by Velocikey when it is enabled: + - RGB Breathing + - RGB Rainbow Mood + - RGB Rainbow Swirl + - RGB Snake + - RGB Knight + +Support for LED breathing effects is planned but not available yet. + + As long as Velocikey is enabled, it will control the speed regardless of any other speed setting that your RGB lights are currently on. + + ## Configuration + Velocikey doesn't currently support any configuration via keyboard settings. If you want to adjust something like the speed increase or decay rate, you would need to edit `velocikey.c` and adjust the values there to achieve the kinds of speeds that you like. diff --git a/feature_wpm.md b/feature_wpm.md new file mode 100644 index 00000000000..12dd0805798 --- /dev/null +++ b/feature_wpm.md @@ -0,0 +1,25 @@ +# Word Per Minute (WPM) Calculcation + +The WPM feature uses time between keystrokes to compute a rolling average words +per minute rate and makes this available for various uses. + +Enable the WPM system by adding this to your `rules.mk`: + + WPM_ENABLE = yes + +For split keyboards using soft serial, the computed WPM +score will be available on the master AND slave half. + +## Public Functions + +`uint8_t get_current_wpm(void);` +This function returns the current WPM as an unsigned integer. + + +## Customized keys for WPM calc + +By default, the WPM score only includes letters, numbers, space and some +punctuation. If you want to change the set of characters considered as part of +the WPM calculation, you can implement `wpm_keycode_user(uint16_t keycode)` +and return true for any characters you would like included in the calculation, +or false to not count that particular keycode. diff --git a/flashing.md b/flashing.md new file mode 100644 index 00000000000..5c245c56754 --- /dev/null +++ b/flashing.md @@ -0,0 +1,242 @@ +# Flashing Instructions and Bootloader Information + +There are quite a few different types of bootloaders that keyboards use, and just about all of them use a different flashing method. Luckily, projects like the [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) aim to be compatible with all the different types without having to think about it much, but this article will describe the different types of bootloaders, and available methods for flashing them. + +If you have a bootloader selected with the `BOOTLOADER` variable in your `rules.mk`, QMK will automatically calculate if your .hex file is the right size to be flashed to the device, and output the total size in bytes (along with the max). + +## DFU + +Atmel's DFU bootloader comes on all atmega32u4 chips by default, and is used by many keyboards that have their own ICs on their PCBs (Older OLKB boards, Clueboards). Some keyboards may also use LUFA's DFU bootloader (or QMK's fork) (Newer OLKB boards) that adds in additional features specific to that hardware. + +To ensure compatibility with the DFU bootloader, make sure this block is present your `rules.mk` (optionally with `lufa-dfu` or `qmk-dfu` instead): + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = atmel-dfu +``` + +Compatible flashers: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) +* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` in QMK (recommended command line) + +Flashing sequence: + +1. Press the `RESET` keycode, or tap the RESET button (or short RST to GND). +2. Wait for the OS to detect the device +3. Erase the memory (may be done automatically) +4. Flash a .hex file +5. Reset the device into application mode (may be done automatically) + +or: + + make ::dfu + +### QMK DFU + +QMK has a fork of the LUFA DFU bootloader that allows for a simple matrix scan for exiting the bootloader and returning to the application, as well as flashing an LED/making a ticking noise with a speaker when things are happening. To enable these features, use this block in your `config.h` (The key that exits the bootloader needs to be hooked-up to the INPUT and OUTPUT defined here): + + #define QMK_ESC_OUTPUT F1 // usually COL + #define QMK_ESC_INPUT D5 // usually ROW + #define QMK_LED E6 + #define QMK_SPEAKER C6 + +The Manufacturer and Product names are automatically pulled from your `config.h`, and "Bootloader" is added to the product. + +To generate this bootloader, use the `bootloader` target, eg `make planck/rev4:default:bootloader`. + +To generate a production-ready .hex file (containing the application and the bootloader), use the `production` target, eg `make planck/rev4:default:production`. + +### DFU commands + +There are a number of DFU commands that you can use to flash firmware to a DFU device: + +* `:dfu` - This is the normal option and waits until a DFU device is available, and then flashes the firmware. This will check every 5 seconds, to see if a DFU device has appeared. +* `:dfu-ee` - This flashes an `eep` file instead of the normal hex. This is uncommon. +* `:dfu-split-left` - This flashes the normal firmware, just like the default option (`:dfu`). However, this also flashes the "Left Side" EEPROM file for split keyboards. _This is ideal for Elite C based split keyboards._ +* `:dfu-split-right` - This flashes the normal firmware, just like the default option (`:dfu`). However, this also flashes the "Right Side" EEPROM file for split keyboards. _This is ideal for Elite C based split keyboards._ + +## Caterina + +Arduino boards and their clones use the [Caterina bootloader](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina) (any keyboard built with a Pro Micro, or clone), and uses the avr109 protocol to communicate through virtual serial. Bootloaders like [A-Star](https://www.pololu.com/docs/0J61/9) are based on Caterina. + +To ensure compatibility with the Caterina bootloader, make sure this block is present your `rules.mk`: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = caterina +``` + +Compatible flashers: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) +* [avrdude](http://www.nongnu.org/avrdude/) with avr109 / `:avrdude` (recommended command line) +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +Flashing sequence: + +1. Press the `RESET` keycode, or short RST to GND quickly (you only have 7 seconds to flash once it enters) +2. Wait for the OS to detect the device +3. Flash a .hex file +4. Wait for the device to reset automatically + +or + + make ::avrdude + + +### Caterina commands + +There are a number of DFU commands that you can use to flash firmware to a DFU device: + +* `:avrdude` - This is the normal option which waits until a Caterina device is available (by detecting a new COM port), and then flashes the firmware. +* `:avrdude-loop` - This runs the same command as `:avrdude`, but after each device is flashed, it will attempt to flash again. This is useful for bulk flashing. _This requires you to manually escape the loop by hitting Ctrl+C._ +* `:avrdude-split-left` - This flashes the normal firmware, just like the default option (`:avrdude`). However, this also flashes the "Left Side" EEPROM file for split keyboards. _This is ideal for Pro Micro based split keyboards._ +* `:avrdude-split-right` - This flashes the normal firmware, just like the default option (`:avrdude`). However, this also flashes the "Right Side" EEPROM file for split keyboards. _This is ideal for Pro Micro based split keyboards._ + + + +## Halfkay + +Halfkay is a super-slim protocol developed by PJRC that uses HID, and comes on all Teensys (namely the 2.0). + +To ensure compatibility with the Halfkay bootloader, make sure this block is present your `rules.mk`: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = halfkay +``` + +Compatible flashers: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) +* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) +* [Teensy Loader Command Line](https://www.pjrc.com/teensy/loader_cli.html) (recommended command line) + +Flashing sequence: + +1. Press the `RESET` keycode, or short RST to GND quickly (you only have 7 seconds to flash once it enters) +2. Wait for the OS to detect the device +3. Flash a .hex file +4. Reset the device into application mode (may be done automatically) + +## USBasploader + +USBasploader is a bootloader developed by matrixstorm. It is used in some non-USB AVR chips such as the ATmega328P, which run V-USB. + +To ensure compatibility with the USBasploader bootloader, make sure this block is present in your `rules.mk`: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = USBasp +``` + +Compatible flashers: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) +* [avrdude](http://www.nongnu.org/avrdude/) with the `usbasp` programmer +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +Flashing sequence: + +1. Press the `RESET` keycode, or keep the boot pin shorted to GND while quickly shorting RST to GND +2. Wait for the OS to detect the device +3. Flash a .hex file +4. Reset the device into application mode (may be done automatically) + +## BootloadHID + +BootloadHID is a USB bootloader for AVR microcontrollers. The uploader tool requires no kernel level driver on Windows and can therefore be run without installing any DLLs. + +To ensure compatibility with the bootloadHID bootloader, make sure this block is present your `rules.mk`: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = bootloadHID +``` + +Compatible flashers: + +* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) (recommended Windows GUI) +* [bootloadhid Command Line](https://www.obdev.at/products/vusb/bootloadhid.html) / `:BootloadHID` in QMK (recommended command line) + +Flashing sequence: + +1. Enter the bootloader using any of the following methods: + * Tap the `RESET` keycode (may not work on all devices) + * Hold the salt key while plugging the keyboard in (usually documented within keyboard readme) +2. Wait for the OS to detect the device +3. Flash a .hex file +4. Reset the device into application mode (may be done automatically) + +or: + + make ::bootloadHID + +## STM32 + +All STM32 chips come preloaded with a factory bootloader that cannot be modified nor deleted. Some STM32 chips have bootloaders that do not come with USB programming (e.g. STM32F103) but the process is still the same. + +At the moment, no `BOOTLOADER` variable is needed on `rules.mk` for STM32. + +Compatible flashers: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) +* [dfu-util](https://github.com/Stefan-Schmidt/dfu-util) / `:dfu-util` (recommended command line) + +Flashing sequence: + +1. Enter the bootloader using any of the following methods: + * Tap the `RESET` keycode (may not work on STM32F042 devices) + * If a reset circuit is present, tap the RESET button + * Otherwise, you need to bridge BOOT0 to VCC (via BOOT0 button or bridge), short RESET to GND (via RESET button or bridge), and then let go of the BOOT0 bridge +2. Wait for the OS to detect the device +3. Flash a .bin file + * You will receive a warning about the DFU signature; Just ignore it +4. Reset the device into application mode (may be done automatically) + * If you are building from command line (e.g. `make planck/rev6:default:dfu-util`), make sure that `:leave` is passed to the `DFU_ARGS` variable inside your `rules.mk` (e.g. `DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave`) so that your device resets after flashing + +### STM32 Commands + +There are a number of DFU commands that you can use to flash firmware to a STM32 device: + +* `:dfu-util` - The default command for flashing to STM32 devices, and will wait until an STM32 bootloader device is present. +* `:dfu-util-split-left` - This flashes the normal firmware, just like the default option (`:dfu-util`). However, this also configures the "Left Side" EEPROM setting for split keyboards. +* `:dfu-util-split-right` - This flashes the normal firmware, just like the default option (`:dfu-util`). However, this also configures the "Right Side" EEPROM setting for split keyboards. +* `:st-link-cli` - This allows you to flash the firmware via ST-LINK's CLI utility, rather than dfu-util. +* `:st-flash` - This allows you to flash the firmware via the `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink), rather than dfu-util. diff --git a/flashing_bootloadhid.md b/flashing_bootloadhid.md new file mode 100644 index 00000000000..731d9277273 --- /dev/null +++ b/flashing_bootloadhid.md @@ -0,0 +1,70 @@ +# BootloadHID Flashing Instructions and Bootloader Information + +ps2avr(GB) boards use an ATmega32A microcontroller and a different bootloader. It is not flashable using the regular QMK methods. + +General flashing sequence: + +1. Enter the bootloader using any of the following methods: + * Tap the `RESET` keycode (may not work on all devices) + * Hold the salt key while plugging the keyboard in (usually documented within keyboard readme) +2. Wait for the OS to detect the device +3. Flash a .hex file +4. Reset the device into application mode (may be done automatically) + +## bootloadHID Flashing Target + +?> Using the QMK installation script, detailed [here](newbs_getting_started.md), the required bootloadHID tools should be automatically installed. + +To flash via the command line, use the target `:bootloadHID` by executing the following command: + + make ::bootloadHID + +## GUI Flashing + +### Windows +1. Download [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash). +2. Place your keyboard into reset. +3. Ensure the configured VendorID is `16c0` and ProductID is `05df` +4. Press the `Find Device` button and ensure that your keyboard is found. +5. Press the `Open .hex File` button and locate the `.hex` file you created. +6. Press the `Flash Device` button and wait for the process to complete. + +## Command Line Flashing + +1. Place your keyboard into reset. +2. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file. + +### Windows Manual Installation +For MSYS2: +1. Download the BootloadHID firmware package from https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz. +2. Extract contents using a compatible tool, for example 7-Zip. +3. Add to the MSYS path by copying `commandline/bootloadHID.exe` from the extracted archive to your MSYS2 installation, typically `C:\msys64\usr\bin`. + +For native Windows flashing, the `bootloadHID.exe` can be used outside of the MSYS2 environment. + +### Linux Manual Installation +1. Install libusb development dependency: + ```bash + # This depends on OS - for Debian the following works + sudo apt-get install libusb-dev + ``` +2. Download the BootloadHID firmware package: + ``` + wget https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -O - | tar -xz -C /tmp + ``` +3. Build the bootloadHID executable: + ``` + cd /tmp/bootloadHID.2012-12-08/commandline/ + make + sudo cp bootloadHID /usr/local/bin + ``` + +### MacOS Manual Installation +1. Install Homebrew by typing the following: + ``` + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + ``` +2. Install the following packages: + ``` + brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb + ``` diff --git a/fr-fr/ChangeLog/20190830.md b/fr-fr/ChangeLog/20190830.md new file mode 100644 index 00000000000..cb223be31ab --- /dev/null +++ b/fr-fr/ChangeLog/20190830.md @@ -0,0 +1,52 @@ +# QMK Breaking Change - 30 août 2019 + +Quatre fois par an, QMK lance un processus pour fusionner les Breaking Changes. Un Breaking Change est un changement qui modifie la manière dont QMK fonctionne introduisant des incompatibilités ou des comportements dangereux. Nous n'effectuons ces changements que 4 fois par an afin que les utilisateurs n'aient pas peur de casser leurs keymaps en mettant à jour leur version de QMK. + +Ce document présente les fusions de Breaking Change. Voici la liste des changements. + +## Formattage de code Core avec clang-format + +* Tous les fichiers core (`drivers/`, `quantum/`, `tests/`, et `tmk_core/`) seront formatés avec clang-format +* Un processus travis pour reformatter les PRs lors de la fusion a été mis en place +* Vous pouvez utiliser la nouvelle commande CLI `qmk cformat` afin de formater avant de soumettre votre PR si vous le souhaitez. + +## Nettoyage des descripteurs LUFA USB + +* Nettoyage du code lié aux descripteurs USB HID sur les claviers AVR, afin de les rendre plus simple à lire et compréhensibles +* Plus d'information: https://github.com/qmk/qmk_firmware/pull/4871 +* Normalement pas de changement de fonctionnement et aucune keymap modifiée. + +## Migration des entrées de `ACTION_LAYER_MOMENTARY()` dans `fn_actions` vers des keycodes `MO()` + +* `fn_actions` est déprécié, et ses fonctionnalités ont été remplacées par des keycodes directs et `process_record_user()` +* Supprimer cette fonctionnalité obsolète devrait aboutir à une réduction importante de la taille du firmware et de la complexité du code +* Il est recommandé que toutes les keymaps affectées remplacent `fn_actions` vers les fonctionnalités de [keycode custom](https://docs.qmk.fm/#/custom_quantum_functions) et [macro](https://docs.qmk.fm/#/feature_macros) + +## Mise à jour Atreus vers les conventions de codage courantes + +* Les doublons include guards ont contourné le comportement de traitement des headers attendu +* Il est recommandé pour toutes les keymaps affectées de supprimer le doublon de `/config.h` et `/keymaps//config.h` et de ne garder que des surcharges au niveau keymap + +## Récupération des changements de fichier keymap langage de la fork ZSA + +* Corrige une issue dans le fichier `keymap_br_abnt2.h` qui inclut la mauvaise souce (`keymap_common.h` au lieu de `keymap.h`) +* Met à jour le fichier `keymap_swedish.h` afin d'être spécifique au suédois et plus "nordique" en général. +* Toutes les keymaps qui utilisent ceci devront supprimer `NO_*` et le remplacer par `SE_*`. + +## Mise à jour du repo afin d'utiliser LUFA comme un sous-module git + +* `/lib/LUFA` supprimé du dépôt +* LUFA, définis comme un sous-module, pointe vers qmk/lufa +* Ceci devrait ajouter plus de flexibilité vers LUFA, et nous permet de garder le sous-module à jour bien plus facilement. Il avait environ 2 ans de retard, sans manière simple de corriger. Ce changement devrait simplifier la mise à jour dans le futur. + +## Migration des entrées `ACTION_BACKLIGHT_*()` dans `fn_actions` vers des keycodes `BL_` + +* `fn_actions` est déprécié, et ses fonctionnalités ont été remplacées par des keycodes directs et `process_record_user()` +* Toutes les keymaps utilisant ces actions doivent avoir les clés `KC_FN*` remplacées par les clés `BL_*` équivalentes +* Si vous utilisez actuellement `KC_FN*` vous devrez remplacer `fn_actions` avec les fonctionnalités de [keycode custom](https://docs.qmk.fm/#/custom_quantum_functions) et [macro](https://docs.qmk.fm/#/feature_macros) + +## Remplacer l'alias `KC_DELT` par `KC_DEL` + +* `KC_DELT` était un alias redondant et non documenté pour `KC_DELETE` +* Il a été supprimé et toutes ses utilisations ont été remplacées par l'alias plus courant `KC_DEL` +* Environ 90 keymaps (surtout des boards ErgoDox) ont été modifiées à cette fin diff --git a/fr-fr/README.md b/fr-fr/README.md new file mode 100644 index 00000000000..3743bedc97d --- /dev/null +++ b/fr-fr/README.md @@ -0,0 +1,32 @@ +# Quantum Mechanical Keyboard Firmware + +[![Version courante](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Statut du build](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Statut de la doc](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![Contributeurs GitHub](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![Forks GitHub](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## Qu'est-ce que QMK Firmware ? + +QMK (*Quantum Mechanical Keyboard*) est une communauté open source qui maintient le firmware QMK, la QMK Toolbox (*Boite à outil*), qmk.fm et leurs documentations. QMK Firmware est un firmware dédié aux claviers qui est basé sur [tmk\_keyboard](http://github.com/tmk/tmk_keyboard). Il offre des fonctionnalités très utiles pour les contrôleurs Atmel AVR, et, plus spécifiquement pour [les produits d'OLKB](http://olkb.com), le clavier [ErgoDox EZ](http://www.ergodox-ez.com), et pour les [produits Clueboard](http://clueboard.co/). Il prend désormais aussi en charge les processeurs ARM qui utilisent ChibiOS. Vous pouvez l'utiliser pour contrôler un clavier personnalisé soudé à la main ou alors sur un clavier avec un PCB personnalisé. + +## Comment l'obtenir + +Si vous souhaitez contribuer à une disposition de clavier (keymap), ou à des fonctionnalités de QMK alors le plus simple est de [forker le dépôt avec GitHub](https://github.com/qmk/qmk_firmware#fork-destination-box) puis cloner le dépôt localement pour y faire des changements. Vous pourrez pousser vos changements sur GitHub puis ouvrir un [Pull Request](https://github.com/qmk/qmk_firmware/pulls) depuis votre fork GitHub. + +Sinon, vous pouvez aussi le télécharger directement en ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), ou le cloner avec git en ssh (`git@github.com:qmk/qmk_firmware.git`), ou https (`https://github.com/qmk/qmk_firmware.git`). + +## Comment le compiler + +Avant d'être prêt à compiler vous allez devoir [installer un environnement](fr-fr/getting_started_build_tools.md) pour les développements AVR et/ou ARM. Une fois ceci fait, vous pourrez utiliser la commande `make` pour compiler le clavier et la disposition avec une commande de ce type : + + make planck/rev4:default + +Cette commande compilera la révision `rev4` du clavier `planck` avec la disposition `default`. Notez que tous les claviers n'ont pas forcément de révisions (aussi appelées sous-projects ou dossiers, ou en anglais « subprojects » ou « folder »). Cette option peut donc être omise : + + make preonic:default + +## Comment le personnaliser + +QMK a beaucoup de [fonctionnalités](fr-fr/features.md) à explorer, et [une documentation](http://docs.qmk.fm) très abondante que vous pourrez parcourir. La plupart des fonctionnalités vous permettrons de modifier vos [dispositions](fr-fr/keymap.md) (keymaps) et de changer [les codes de caractères](fr-fr/keycodes.md) (keycodes). diff --git a/fr-fr/_summary.md b/fr-fr/_summary.md new file mode 100644 index 00000000000..25a593b2ec2 --- /dev/null +++ b/fr-fr/_summary.md @@ -0,0 +1,126 @@ +**En Français** + +* [Guide pour débutant complet](fr-fr/newbs.md) + * [Pour débuter](fr-fr/newbs_getting_started.md) + * [Compiler son premier firmware](fr-fr/newbs_building_firmware.md) + * [Flasher le Firmware](fr-fr/newbs_flashing.md) + * [Test et Débuggage](fr-fr/newbs_testing_debugging.md) + * [Bonnes pratiques Git](fr-fr/newbs_best_practices.md) + * [Ressources d'apprentissage](fr-fr/newbs_learn_more_resources.md) + +* [Les bases de QMK](fr-fr/README.md) + * [Indroduction à QMK](fr-fr/getting_started_introduction.md) + * [QMK CLI](fr-fr/cli.md) + * [Configuration de la CLI QMK](fr-fr/cli_configuration.md) + * [Contribuer à QMK](fr-fr/contributing.md) + * [Comment utiliser GitHub](fr-fr/getting_started_github.md) + * [Trouver de l'aide](fr-fr/getting_started_getting_help.md) + +* [Breaking changes](fr-fr/breaking_changes.md) + * [30 août 2019](fr-fr/ChangeLog/20190830.md) + +* [FAQ](fr-fr/faq.md) + * [FAQ Générale](fr-fr/faq_general.md) + * [Compiler QMK](fr-fr/faq_build.md) + * [Débugguer / Dépanner QMK](fr-fr/faq_debug.md) + * [Keymap / Disposition](fr-fr/faq_keymap.md) + * [Installer les drivers avec Zadig](fr-fr/driver_installation_zadig.md) + +**En Anglais** + +* Guides détaillés + * [Installation des outils de compilation](fr-fr/getting_started_build_tools.md) + * [Guide Vagrant](fr-fr/getting_started_vagrant.md) + * [Commandes de compilations](fr-fr/getting_started_make_guide.md) + * [Flasher les firmwares](fr-fr/flashing.md) + * [Personnaliser les fonctionnalités](fr-fr/custom_quantum_functions.md) + * [Aperçu des fonctionnalités des dispositions](fr-fr/keymap.md) + +* [Hardware](fr-fr/hardware.md) + * [Processeurs AVR](fr-fr/hardware_avr.md) + * [Pilotes / Drivers](fr-fr/hardware_drivers.md) + +* Réferences + * [Lignes de conduite des claviers](fr-fr/hardware_keyboard_guidelines.md) + * [Options de configurations](fr-fr/config_options.md) + * [Keycodes / Codes des caractères](fr-fr/keycodes.md) + * [Conventions de codage - C](fr-fr/coding_conventions_c.md) + * [Conventions de codage - Python](fr-fr/coding_conventions_python.md) + * [Meilleurs pratiques sur la documentation](fr-fr/documentation_best_practices.md) + * [Modèles de documentation](fr-fr/documentation_templates.md) + * [Glossaire](fr-fr/reference_glossary.md) + * [Tests unitaires](fr-fr/unit_testing.md) + * [Fonctions utiles](fr-fr/ref_functions.md) + * [Support de configuration](fr-fr/reference_configurator_support.md) + * [Format du fichier info.json](fr-fr/reference_info_json.md) + * [Développer la CLI en Python](fr-fr/cli_development.md) + +* [Fonctionnalités](fr-fr/features.md) + * [Keycodes basiques](fr-fr/keycodes_basic.md) + * [Touches utilisées avec Shift (US ANSI)](fr-fr/keycodes_us_ansi_shifted.md) + * [Keycodes quantiques](fr-fr/quantum_keycodes.md) + * [Keycodes avancés](fr-fr/feature_advanced_keycodes.md) + * [Fonctionnalités audio](fr-fr/feature_audio.md) + * [Majuscule automatique](fr-fr/feature_auto_shift.md) + * [Rétroéclairage](fr-fr/feature_backlight.md) + * [Bluetooth](fr-fr/feature_bluetooth.md) + * [Bootmagic](fr-fr/feature_bootmagic.md) + * [Combos](fr-fr/feature_combo.md) + * [Commande](fr-fr/feature_command.md) + * [API anti-rebond](fr-fr/feature_debounce_type.md) + * [DIP Switch](fr-fr/feature_dip_switch.md) + * [Macros dynamiques](fr-fr/feature_dynamic_macros.md) + * [Interrupteurs rotatifs](fr-fr/feature_encoders.md) + * [Grave Escape](fr-fr/feature_grave_esc.md) + * [Retour haptique](fr-fr/feature_haptic_feedback.md) + * [Contrôleur LCD HD44780](fr-fr/feature_hd44780.md) + * [Touche à verrou / Lock-key](fr-fr/feature_key_lock.md) + * [Dispositions / layouts](fr-fr/feature_layouts.md) + * [Touche leader](fr-fr/feature_leader_key.md) + * [Matrice LED](fr-fr/feature_led_matrix.md) + * [Macros](fr-fr/feature_macros.md) + * [Boutons de souris](fr-fr/feature_mouse_keys.md) + * [Pilotes / Drivers OLED](fr-fr/feature_oled_driver.md) + * [Touche one-shot](fr-fr/one_shot_keys.md) + * [Périphériques de pointage](fr-fr/feature_pointing_device.md) + * [Souris PS/2](fr-fr/feature_ps2_mouse.md) + * [Éclairage RGB](fr-fr/feature_rgblight.md) + * [Matrice RGB](fr-fr/feature_rgb_matrix.md) + * [Space Cadet](fr-fr/feature_space_cadet.md) + * [Claviers scindés / splittés](fr-fr/feature_split_keyboard.md) + * [Stenographie](fr-fr/feature_stenography.md) + * [Inversion des mains](fr-fr/feature_swap_hands.md) + * [Tap Dance](fr-fr/feature_tap_dance.md) + * [Terminale](fr-fr/feature_terminal.md) + * [Imprimante thermique](fr-fr/feature_thermal_printer.md) + * [Caractères unicodes](fr-fr/feature_unicode.md) + * [Dossier utilisateur](fr-fr/feature_userspace.md) + * [Velocikey](fr-fr/feature_velocikey.md) + +* Pour les makers et les bricoleurs + * [Guide des claviers soudés à la main](fr-fr/hand_wire.md) + * [Guide de flash de l’ISP](fr-fr/isp_flashing_guide.md) + * [Guide du débogage ARM](fr-fr/arm_debugging.md) + * [Drivers I2C](fr-fr/i2c_driver.md) + * [Drivers SPI](fr-fr/spi_driver.md) + * [Contrôles des GPIO](fr-fr/internals_gpio_control.md) + * [Conversion en Proton C](fr-fr/proton_c_conversion.md) + +* Pour aller plus loin + * [Comment fonctionnent les claviers](fr-fr/how_keyboards_work.md) + * [Comprendre QMK](fr-fr/understanding_qmk.md) + +* Autres sujets + * [Utiliser Eclipse avec QMK](fr-fr/other_eclipse.md) + * [Utiliser VSCode avec QMK](fr-fr/other_vscode.md) + * [Support](fr-fr/getting_started_getting_help.md) + * [Comment ajouter des traductions](fr-fr/translating.md) + +* À l’intérieur de QMK (En cours de documentation) + * [Définitions](fr-fr/internals_defines.md) + * [Input Callback Reg](fr-fr/internals_input_callback_reg.md) + * [Appareils Midi](fr-fr/internals_midi_device.md) + * [Installation d’un appareil Midi](fr-fr/internals_midi_device_setup_process.md) + * [Utilitaires Midi](fr-fr/internals_midi_util.md) + * [Fonctions Midi](fr-fr/internals_send_functions.md) + * [Outils Sysex](fr-fr/internals_sysex_tools.md) diff --git a/fr-fr/breaking_changes.md b/fr-fr/breaking_changes.md new file mode 100644 index 00000000000..2dbb26e5a5b --- /dev/null +++ b/fr-fr/breaking_changes.md @@ -0,0 +1,107 @@ +# Breaking changes + +Ce document décrit le processus de QMK pour la gestion des breaking changes. Un breaking change est un changement qui modifie la manière dont QMK fonctionne introduisant des incompatibilités ou des comportements dangereux. Nous limitons ces changements afin que les utilisateurs n'aient pas peur de casser leurs keymaps en mettant à jour leur version de QMK. + +La période de breaking change est quand nous allons fusionner un PR qui change QMK d'une manière dangereuse ou inattendue. Il y a une période interne de test afin de nous assurer que les problèmes résiduels sont rares ou impossible à prévoir. + +## Qu'est-ce qui a été inclus dans des Breaking Changes précédents? + +* [30 août 2019](ChangeLog/20190830.md) + +## Quand va être le prochain Breaking Change? + +Le prochain Breaking Change est planifié pour le 29 novembre. + +### Dates importantes + +* [x] 21 septembre 2019 - `future` est créé. Il va être rebasé de manière hebdomadaire. +* [ ] 01 novembre 2019 - `future` fermé aux nouveaux PRs. +* [ ] 01 novembre 2019 - Appel aux testeurs. +* [ ] 27 novembre 2019 - `master` est bloqué, pas de PRs fusionnés. +* [ ] 29 novembre 2019 - `future` est fusionné dans `master`. +* [ ] 30 novembre 2019 - `master` est débloqué. Les PRs peuvent à nouveau être fusionnés. + +## Quels changements seront inclus? + +Pour voir une liste de candidats de breaking changes, vous pouvez regarder la liste des [labels `breaking_change`](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Abreaking_change+is%3Apr). De nouveaux changements peuvent être ajoutés entre maintenant et lorsque `future` est fermée, et un PR avec ce label n'est pas garanti d'être fusionné. + +Si vous souhaitez que votre breaking change soit inclus dans ce tour, vous devez créer un PR avec le label `breaking_change` et faire en sorte qu'il soit accepté avant que `future` ne soit fermé. Une fois `future` fermé, aucun nouveau breaking change sera accepté. + +Critère d'acceptation: + +* Le PR est complété et prêt à fusionner +* Le PR a un ChangeLog + +# Checklists + +Cette section documente plusieurs processus que nous utilisons en lançant le processus de Breaking Change. + +## Rebase `future` de `master` + +Ceci est lancé chaque vendredi tant que `future` est ouvert. + +Processus: + +``` +cd qmk_firmware +git checkout master +git pull --ff-only +git checkout future +git rebase master +git push --force +``` + +## Créer la branche `future` + +Ceci est fait immédiatement après la fusion de la branche `future` précédente. + +* `qmk_firmware` git commands + * [ ] `git checkout master` + * [ ] `git pull --ff-only` + * [ ] `git checkout -b future` + * [ ] Modifie `readme.md` + * [ ] Ajoute un message en haut qui indique que c'est une branche de test. + * [ ] Ajoute un lien vers ce document + * [ ] `git commit -m 'Branch point for Breaking Change'` + * [ ] `git tag breakpoint___
` + * [ ] `git tag ` # Evite que le label point d'arrêt soit confondu par un incrément de version + * [ ] `git push origin future` + * [ ] `git push --tags` + +## 4 Semaines Avant la Fusion + +* `future` est maintenant fermé aux nouveaux PRs, seul des correctifs pour les PRs courants peuvent être mergés +* Envoi de l'appel aux testeurs + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## 1 Semaine Avant la Fusion + +* Annonce que master sera fermée entre <2 jours avant> à + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## 2 Jours Avant la Fusion + +* Annonce que master est fermé pour 2 jours + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## Jour de la fusion + +* `qmk_firmware` git commands + * [ ] `git checkout future` + * [ ] `git pull --ff-only` + * [ ] `git rebase origin/master` + * [ ] Modifie `readme.md` + * [ ] Supprimer les notes à propos de `future` + * [ ] Regroupe ChangeLog dans un fichier. + * [ ] `git commit -m 'Merge point for Breaking Change'` + * [ ] `git push origin future` +* Actions sur GitHub + * [ ] Crée un PR pour `future` + * [ ] S'assurer que Travis ne relève aucun problème + * [ ] Fusion le PR `future` diff --git a/fr-fr/cli.md b/fr-fr/cli.md new file mode 100644 index 00000000000..42815364582 --- /dev/null +++ b/fr-fr/cli.md @@ -0,0 +1,146 @@ +# La CLI de QMK + +Cette page décrit comment configurer et utiliser la CLI QMK. + +# Vue d'ensemble + +La CLI de QMK permet de simplifier la compilation et l'interaction avec les claviers QMK. Nous avons défini plusieurs commandes pour simplifier et rationaliser les tâches telles qu'obtenir et compiler le firmware QMK, créer de nouvelles keymaps, et plus. + +* [CLI globale](#global-cli) +* [CLI locale](#local-cli) +* [Les commandes CLI](#cli-commands) + +# Pré-requis + +La CLI nécessite Python 3.5 ou plus récent. Nous essayons de limiter le nombre de pré-requis, mais vous allez aussi devoir installer les paquets listés dans le fichier [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). + +# CLI globale + +QMK met à disposition une CLI installable qui peut être utilisée pour configurer votre environnement de compilation QMK, fonctionne avec QMK, et qui rend l'utilisation de plusieurs copies de `qmk_firmware` plus simple. Nous recommandons d'installer et de mettre à jour ceci régulièrement. + +## Installer en utilisant Homebrew (macOS, quelques Linux) + +Si vous avez installé [Homebrew](https://brew.sh) vous pouvez entrer ce qui suit et installer QMK: + +``` +brew tap qmk/qmk +brew install qmk +export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` +qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment +``` + +## Installer en utilisant easy_install ou pip + +Si votre système n'est pas listé ci-dessus, vous pouvez installer QMK manuellement. Premièrement, vérifiez que vous avez bien installé Python 3.5 (ou plus récent) et pip. Ensuite, installez QMK avec cette commande: + +``` +pip3 install qmk +export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` +qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment +``` + +## Paquets pour d'autres systèmes d'exploitation + +Nous recherchons des gens pour créer et maintenir un paquet `qmk` pour plus de systèmes d'exploitation. Si vous voulez créer un paquet pour votre système d'exploitation, suivez ces directives: + +* Suivez les bonnes pratiques pour votre système d'exploitation lorsqu'elles entrent en conflit avec ces directives + * Documentez pourquoi dans un commentaire lorsque vous ne les suivez pas +* Installez en utilisant un virtualenv +* Expliquez à l'utilisateur de définir la variable d'environnement `QMK_Home` pour "check out" les sources du firmware à un autre endroit que `~/qmk_firmware`. + +# CLI locale + +Si vous ne voulez pas utiliser la CLI globale, il y a une CLI locale empaquetée avec `qmk_firmware`. Vous pouvez le trouver dans `qmk_firmware/bin/qmk`. Vous pouvez lancer la commande `qmk` depuis n'importe quel répertoire et elle fonctionnera toujours sur cette copie de `qmk_firmware`. + +**Exemple**: + +``` +$ ~/qmk_firmware/bin/qmk hello +Ψ Hello, World! +``` + +## Limitations de la CLI locale + +Il y a quelques limitations à la CLI locale comparé à la globale: + +* La CLI locale ne supporte pas `qmk setup` ou `qmk clone` +* La CLI locale n'opère pas sur le même arbre `qmk_firmware`, même si vous avez plusieurs dépôts clonés. +* La CLI locale ne s'exécute pas dans un virtualenv, donc il y a des risques que des dépendances seront en conflit + +# Les commandes CLI + +## `qmk compile` + +Cette commande permet de compiler le firmware de n'importe quel répertoire. Vous pouvez compiler des exports JSON de ou compiler des keymaps du dépôt. + +**Utilisation pour les exports de configuration**: + +``` +qmk compile +``` + +**Utilisation pour les Keymaps**: + +``` +qmk compile -kb -km +``` + +## `qmk cformat` + +Cette commande formatte le code C en utilisant clang-format. Lancez-la sans arguments pour formatter tout le code core, ou passez les noms de fichiers à la ligne de commande pour la lancer sur des fichiers spécifiques. + +**Utilisation**: + +``` +qmk cformat [file1] [file2] [...] [fileN] +``` + +## `qmk config` + +Cette commande vous permet de configurer le comportement de QMK. Pour la documentation complète de `qmk config`, regardez [Configuration de CLI](cli_configuration.md). + +**Utilisation**: + +``` +qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] +``` + +## `qmk doctor` + +Cette commande examine votre environnement et vous alertes des potentiels problèmes de compilation ou de flash. + +**Utilisation**: + +``` +qmk doctor +``` + +## `qmk new-keymap` + +Cette commande crée une nouvelle keymap basée sur une keymap par défaut d'un clavier existant. + +**Utilisation**: + +``` +qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] +``` + +## `qmk pyformat` + +Cette commande formate le code python dans `qmk_firmware`. + +**Utilisation**: + +``` +qmk pyformat +``` + +## `qmk pytest` + +Cette commande démarre la suite de test python. Si vous faites des changements dans le code Python, assurez-vous que les tests se lancent avec succès. + +**Utilisation**: + +``` +qmk pytest +``` diff --git a/fr-fr/cli_configuration.md b/fr-fr/cli_configuration.md new file mode 100644 index 00000000000..3eed1e0e950 --- /dev/null +++ b/fr-fr/cli_configuration.md @@ -0,0 +1,121 @@ +# Configuration de QMK CLI + +Ce document explique comment fonctionne la commande `qmk config`. + +# Introduction + +La configuration pour QMK CLI est un système clé/valeur. Chaque clé est composée d'une sous-commande et d'un argument séparé par une virgule. Cela permet une traduction simple et directe entre les clés de configuration et l'argument qu'elle définit. + +## Exemple simple + +Comme exemple, regardons la commande `qmk compile --keyboard clueboard/66/rev4 --keymap default`. + +Il y a deux arguments de ligne de commande qui peuvent être lu de la configuration: + +* `compile.keyboard` +* `compile.keymap` + +Essayons de les définir: + +```shell +$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default +compile.keyboard: None -> clueboard/66/rev4 +compile.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +Maintenant, je peux lancer la commande `qmk compile` sans avoir à spécifier mon clavier et keymap à chaque fois. + +## Définir les options par défaut + +Parfois, il est utile de partager une configuration entre plusieurs commandes. Par exemple, plusieurs commandes prennent un argument `--keyboard`. Plutôt que de devoir définir cette valeur pour chaque commande, vous pouvez définir une valeur d'utilisateur qui sera utilisée par toutes les commandes qui prennent cet argument. + +Exemple: + +``` +$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default +user.keyboard: None -> clueboard/66/rev4 +user.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# CLI Documentation (`qmk config`) + +La commande `qmk config` est utilisée pour interagir avec la configuration sous-jacente. Lancée sans argument, elle affiche la configuration courante. Lorsque des arguments sont définis, ils sont considérés comme étant des jetons de configuration, qui sont des chaînes de caractère ne contenant aucun espace avec le format suivant: + + [.][=] + +## Définir des valeurs de configuration + +Vous pouvez définir des valeurs de configuration en mettant le caractère égal (=) dans votre clé de configuration. La clé doit toujours être dans le format complet `
.`. + +Exemple: + +``` +$ qmk config default.keymap=default +default.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## Lire des valeurs de configuration + +Vous pouvez lire les valeurs de configuration pour la totalité de la configuration, une seule clé, ou une section entière. Vous pouvez aussi spécifier plusieurs clés pour afficher plus d'une valeur. + +### Exemple avec la totalité de la configuration + + qmk config + +### Exemple avec une section entière + + qmk config compile + +### Exemple avec une clé unique + + qmk config compile.keyboard + +### Exemple avec plusieurs clés + + qmk config user compile.keyboard compile.keymap + +## Supprimer des valeurs de configuration + +Vous pouvez supprimer une valeur de configuration en la définissant avec la chaîne spéciale `None`. + +Exemple: + +``` +$ qmk config default.keymap=None +default.keymap: default -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## Plusieurs opérations + +Vous pouvez combiner plusieurs opérations d'écriture et de lecture en une seule commande. Elles seront exécutées et affichées dans l'ordre: + +``` +$ qmk config compile default.keymap=default compile.keymap=None +compile.keymap=skully +compile.keyboard=clueboard/66_hotswap/gen1 +default.keymap: None -> default +compile.keymap: skully -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# Options de configuration utilisateur + +| Clé | Valeur par défaut | Description | +|-----|---------------|-------------| +| user.keyboard | None | Le chemin d'accès vers le clavier (Exemple: `clueboard/66/rev4`) | +| user.keymap | None | Le nom de la keymap (Exemple: `default`) | +| user.name | None | Le nom d'utilisateur GitHub de l'utilisateur. | + +# Toutes les options de configuration + +| Clé | Valeur par défaut | Description | +|-----|---------------|-------------| +| compile.keyboard | None | Le chemin d'accès vers le clavier (Exemple: `clueboard/66/rev4`) | +| compile.keymap | None | Le nom de la keymap (Exemple: `default`) | +| hello.name | None | Le nom à saluer lorsque démarré. | +| new_keyboard.keyboard | None | Le chemin d'accès vers le clavier (Exemple: `clueboard/66/rev4`) | +| new_keyboard.keymap | None | Le nom de la keymap (Example: `default`) | diff --git a/fr-fr/contributing.md b/fr-fr/contributing.md new file mode 100644 index 00000000000..0092d664efb --- /dev/null +++ b/fr-fr/contributing.md @@ -0,0 +1,154 @@ +# Comment contribuer + +👍🎉 Premièrement, merci de prendre le temps de lire ceci et de contribuer! 🎉👍 + +Les contributions de tiers nous aide à améliorer et faire grandir QMK. Nous voulons rendre les pull requests et le processus de contribution utile et simple à la fois pour les contributeurs et les mainteneurs. C'est pourquoi nous avons mis en places des directives pour les contributeurs afin que votre pull request puisse être accepté sans changement majeur. + +* [Aperçu du projet](#project-overview) +* [Conventions de codage](#coding-conventions) +* [Directives générales](#general-guidelines) +* [Que veut dire le code de conduite pour moi?](#what-does-the-code-of-conduct-mean-for-me) + +## Je ne veux pas lire tout ce pavé! J'ai juste une question! + +Si vous voulez poser une question sur QMK, vous pouvez le faire sur le [sous-reddit OLKB](https://reddit.com/r/olkb) ou sur [Discord](https://discord.gg/Uq7gcHh). + +Merci de garder ceci en tête: + +* Cela peut prendre plusieurs heures pour que quelqu'un réponde à votre question. Merci d'être patient! +* Tous ceux impliqués avec QMK fait don de son temps et de son énergie. Nous ne sommes pas payés pour travailler sur ou répondre aux questions concernant QMK. +* Essayez de poser vos questions de manière à ce qu'elles soient le plus simple à répondre possible. Si vous n'êtes pas sûrs de savoir comment faire, voici quelques bon guides (en anglais): + * https://opensource.com/life/16/10/how-ask-technical-questions + * http://www.catb.org/esr/faqs/smart-questions.html + +# Aperçu du projet + +QMK est majoritairement écrit en C, avec quelques fonctions et parties spécifiques écrites en C++. Il est destiné aux processeurs intégrés que l'on trouve dans des clavier, particulièrement AVR ([LUFA](http://www.fourwalledcubicle.com/LUFA.php)) et ARM ([ChibiOS](http://www.chibios.com)). Si vous maîtrisez déjà la programmation sur Arduino, vous trouverez beaucoup de concepts et de limitations familiers. Une expérience préalable avec les Arduino n'est pas nécessaire à contribuer avec succès à QMK. + + + +# Où trouver de l'aide? + +Si vous avez besoin d'aide, vous pouvez [ouvrir une issue](https://github.com/qmk/qmk_firmware/issues) ou [un chat sur Discord](https://discord.gg/Uq7gcHh). + +# Comment contribuer? + +Vous n'avez encore jamais contribué à un projet open source? Vous vous demandez comment les contributions dans QMK fonctionnent? Voici un aperçu rapide! + +0. Enregistrez-vous sur [GitHub](https://github.com). +1. Définissez une keymap à contribuer, [trouvez une issue](https://github.com/qmk/qmk_firmware/issues) que vous souhaitez corriger, ou [une fonction](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) que vous voulez ajouter. +2. Créez un fork sur le dépôt associé avec une issue sur votre compte GitHub. Cela veut dire que vous allez avoir une copie du dépôt sous `votre-login-GitHub/qmk_firmware`. +3. Clonez le dépôt sur votre machine locale en utilisant `git clone https://github.com/login-github/repository-name.git`. +4. Si vous travaillez sur une nouvelle fonctionnalité, pensez à ouvrir une issue pour parler avec nous du travail que vous souhaitez démarrer. +5. Créez une nouvelle branche pour votre correctif en utilisant `git checkout -b nom-de-branche`. +6. Faites les changements nécessaires pour corriger le problème ou ajouter la fonctionnalité. +7. Utilisez `git add chemin-de-fichier` pour ajouter les contenus des fichiers modifiés au "snapshot" que git utilise pour gérer l'état du projet, appelé aussi l'index. +8. Utilisez `git commit -m "Insérez une description courte des changements (en anglais)"` pour enregistrer le contenu de l'index avec un message descriptif. +9. Poussez les changements vers votre dépôt sur GitHub en utilisant `git push origin nom-de-branche`. +10. Créez un pull request sur [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master). +11. Donnez un titre à votre pull request en utilisant une description courte des changements que vous avez fait et ajoutez le numéro de l'issue ou du bug associé avec votre changement. Les commentaires de PR devraient se faire en anglais de préférence. Par exemple, vous pouvez utiliser un titre tel que celui-là: "Added more log outputting to resolve #4352". +12. Dans la description du pull request, expliquez les changements que vous avez fait et tous les problèmes qui existent, selon vous, sur le pull request que vous avez fait. Vous pouvez aussi utiliser la description pour poser des questions au mainteneur. Il n'est pas nécessaire que votre pull request soit parfait (aucun pull request ne l'est), le reviewer sera là pour vous aider à résoudre les problèmes et l'améliorer! +13. Attendez que le pull request soit revu par un mainteneur. +14. Faites des changements au pull request si le mainteneur le recommande. +15. Célébrez votre succès une fois votre pull request fusionné! + +# Conventions de codage + +La grande majorité de notre style est plutôt simple à comprendre. Si vous connaissez C ou Python, vous ne devriez pas avoir trop de difficulté avec notre style. + +* [Conventions de codage - C](coding_conventions_c.md) +* [Conventions de codage - Python](coding_conventions_python.md) + +# Directives générales + +Nous avons un certain nombre de type de changements dans QMK, chacun nécessitant un niveau de rigueur différent. Nous voulons que vous gardiez les directives suivantes en tête quel que soit le changement que vous êtes en train de faire. + +* Séparez les PR dans des unités logiques. Par exemple, ne soumettez pas un PR qui couvre deux fonctionnalités séparées, soumettez plutôt un PR pour chaque fonctionnalité. +* Vérifiez les espaces blancs non nécessaires avec `git diff --check` avant de commit. +* Assurez-vous que votre code compile. + * Keymaps: Assurez-vous que `make keyboard:your_new_keymap` ne renvoie pas d'erreur. + * Claviers: Assurez-vous que `make keyboard:all` ne renvoie pas d'erreur. + * Core: Assurez-vous que `make all` ne renvoie pas d'erreur. +* Assurez-vous que les messages de commit soient compréhensibles d'eux-mêmes. Vous devriez écrire une description simple (pas plus de 70 caractères) sur la première ligne, suivi d'une ligne vide, suivi d'un détail de votre commit, si nécessaire. Exemple: + +``` +Adjust the fronzlebop for the kerpleplork + +The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations. + +Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure. +``` + +## Documentation + +La documentation est l'une des manières les plus simples de démarrer la contribution sur QMK. Il est simple de trouver des endroits où la documentation est fausse ou incomplète, et il est tout aussi simple de la corriger! Nous avons aussi grandement besoin de quelqu'un pour éditer notre documentation, donc si vous avez des compétences en édition mais que vous n'êtes pas sûr de savoir où aller, n'hésitez pas [demandez de l'aide](#where-can-i-go-for-help)! + +Vous trouverez toute notre documentation dans le répertoire `qmk_firmware/docs`, ou si vous préférez utiliser des outils web, vous pouvez cliquer sur le bouton "Suggest An Edit" en haut de chaque page sur http://docs.qmk.fm/. + +Lorsque vous donnez des exemples de code dans la documentation, essayez de suivre les conventions de nommage utilisées ailleurs dans la documentation. Par exemple, standardisez les enums en utilisant `my_layers` ou `my_keycodes` afin de garder une consistance: + +```c +enum my_layers { + _FIRST_LAYER, + _SECOND_LAYER +}; + +enum my_keycodes { + FIRST_LAYER = SAFE_RANGE, + SECOND_LAYER +}; +``` + +## Keymaps + +La plupart des contributeurs débutants démarrent avec leurs keymaps personnelles. Nous essayons de garder les standards pour les keymaps pluôt simple (les keymaps reflètent, après tout, la personnalité de leurs créateurs) mais nous demandons que vous suiviez les directives suivantes afin que d'autres puissent découvrir et apprendre de votre keymap. + +* Ecrivez un fichier `readme.md` en utilisant [la template](documentation_templates.md). +* Tous les PR de keymaps doivent être "squashés", donc si la manière dont vos commits sont squashés vous est important, vous devez le faire vous-même. +* Ne regroupez pas des fonctionnalités avec votre PR de keymap. Envoyez d'abord votre fonctionnalité, puis créez un second PR pour la keymap. +* N'incluez pas de fichier `Makefile` dans votre dossier de keymap (ils ne sont plus utilisés) +* Mettez à jour les copyrights dans les en-têtes de fichiers (cherchez `%YOUR_NAME%`) + +## Claviers + +Les claviers sont la raison d'être de QMK. Certains claviers sont maintenus par la communauté, alors que d'autre sont maintenus par les gens responsables de la création du clavier. Le fichier `readme.md` devrait vous informer de qui maintient le clavier. Si vous avez des questions concernant un clavier en particulier, vous pouvez [Ouvrir une issue](https://github.com/qmk/qmk_firmware/issues) et tagger le mainteneur dans votre question. + +Nous vous demandons aussi que vous suiviez ces directives: + +* Ecrivez un fichier `readme.md` en utilisant [le template](documentation_templates.md). +* Gardez un nombre de commits raisonnable, ou nous squasherons votre PR. +* Ne regroupez pas des fonctionnalités avec le PR pour votre clavier. Envoyez d'abord votre fonctionnalité, puis créez un second PR pour le clavier. +* Appelez les fichiers `.c`/`.h` du nom du dossier parent, par exemple `/keyboards///.[ch]` +* N'incluez pas de fichier `Makefile` dans votre dossier de keymap (ils ne sont plus utilisés) +* Mettez à jour les copyrights dans les en-têtes de fichiers (cherchez `%YOUR_NAME%`) + +## Quantum/TMK Core + +Faites attention d'être sûr d'implémenter votre nouvelle fonctionnalité de la meilleure manière qu'il soit avant d'investir beaucoup de travail à son développement. Vous pouvez apprendre les bases de QMK en lisant [Comprendre QMK](understanding_qmk.md), qui vous donnera une idée du flux du programme QMK. A partir de là, parlez nous afin de définir la meilleure façon d'implémenter votre idée. Il y a deux façons principale de le faire: + +* [Chat sur Discord](https://discord.gg/Uq7gcHh) +* [Ouvrir une Issue](https://github.com/qmk/qmk_firmware/issues/new) + +Les PR de nouvelles fonctionnalités de de correction de bug affectent tous les claviers. Nous sommes aussi dans un processus de restructuration de QMK. Pour cette raison, il est absolument nécessaire que tout changement important ou significatif soit discuté avant que l'implémentation soit faite. Si vous ouvrez un PR sans nous avoir parlé, préparez-vous à faire des refontes significatives si vos changements ne sont pas compatibles avec ce que nous avons planifié. + +Voici quelques choses à garder en tête lorsque vous travaillez sur une fonctionnalité ou un bug fix. + +* **Désactivé par défaut** - la mémoire est plutôt limitée sur la plupart des puces que QMK supporte, et il est important que les keymaps courantes ne soient pas cassées. S'il vous plaît faites que vos features doivent être **activées** plutôt que désactivées. Si vous pensez qu'elle devrait être activée par défaut, ou que cela réduit la taille du code, parlez-nous-en. +* **Compilez localement avant de soumettre** - Cela devrait aller sans dire, mais votre code doit compiler! Notre système Travis devrait relever les problèmes, mais il est généralement plus rapide de compiler quelques claviers en local plutôt que d'attendre le retour des résultats +* **Faites attention aux révisions et différentes bases de puces** - beaucoup de claviers ont des révisions qui permettent des changements de configuration mineurs, voir des bases de chip différentes. Essayez de faire que votre fonctionnalité soit supportée à la fois sur ARM et AVR, ou désactivez-là automatiquement sur les plateformes non supportées. +* **Expliquez votre fonctionnalité** - Documentez-là dans `docs/`, soit dans un nouveau fichier, ou dans une partie d'un fichier existant. Si vous ne la documentez pas, personne ne pourra bénéficier de votre dur labeur. + +Nous vous demandons aussi de suivre ces directives: + +* Gardez un nombre de commits raisonnable, ou nous squasherons votre PR. +* Ne regroupez pas des claviers ou des keymaps avec des changements core. Soumettez vos changements core en premier. +* Ecrivez des [Tests Unitaires](unit_testing.md) pour votre fonctionnalité. +* Suivez le style du fichier que vous modifiez. Si le style n'est pas clair ou qu'il y a un mélange de fichiers, vous devriez vous conformer aux [conventions de codage](#coding-conventions) au dessus. + +## Refactoriser + +Afin de maintenir une vision claire sur comment les choses sont architectuées dans QMK, nous essayons de planifier des refactorisations en profondeur et qu'un collaborateur fasse le changement. Si vous avez une idée de refactorisation, ou une suggestion, [ouvrez une issue] [open an issue](https://github.com/qmk/qmk_firmware/issues), nous adorons discuter de comment améliorer QMK. + +# Que veut dire le code de conduite pour moi? + +Note [Code De Conduite](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md) veut dire que vous avez la responsabilité de traiter tout le monde dans le projet avec respect et courtoisie, peu importe leur identité. Si vous êtes victime d'une attitude ou de commentaires inappropriés, tels que décrit dans notre Code de Conduite, nous sommes là pour vous et nous ferons de notre mieux pour nous assurer que le fautif soit réprimandé, tel que décrit dans notre code. diff --git a/fr-fr/driver_installation_zadig.md b/fr-fr/driver_installation_zadig.md new file mode 100644 index 00000000000..9e7d77b6dc4 --- /dev/null +++ b/fr-fr/driver_installation_zadig.md @@ -0,0 +1,46 @@ +# Installation du driver du bootloader avec Zadig + +Vous n’aurez pas besoin de pilote particulier pour utiliser un clavier QMK. En effet, QMK se présente à l'ordinateur hôte comme un clavier HID standard et sera reconnu sans problème. Cependant vous aurez peut-être besoin d'un pilote pour flasher votre clavier avec Windows. En effet, quand vous redémarrerez votre clavier en mode bootloader, le périphérique que détectera Windows ne sera pas un clavier mais un périphérique bootloader. + +Il existe deux exceptions : le bootloader Caterina, qui se trouve en général sur les Pro Micros, et le bootloader Halfkay, livré avec les Teensy de PJRC. Ils apparaissent respectivement sous la forme d'un port série et d'un périphérique HID générique, ne nécessitant pas de pilote particulier. + +Nous vous recommandons d'utiliser l'utilitaire [Zadig](https://zadig.akeo.ie/). Si vous avez configuré votre environnement de développement avec Msys2 ou WSL, le script `qmk_install.sh` vous aura proposé l'installation des pilotes durant le processus. + +## Installation + +Passez votre clavier en mode bootloader, soit en appuyant sur le keycode `RESET` (qui peut se trouver dans un calque différent) ou en appuyant sur le bouton reset qui se trouve en général sous la board. Si votre clavier n'a aucune de ces options, essayez de le brancher en maintenant Escape ou Espace+`B` appuyés (voir la documentation de [Bootmagic](feature_bootmagic.md) pour plus de détails). Certaines boards utilisent [Command](feature_command.md) à la place de Bootmagic. Dans ce cas, vous pouvez entrer en mode bootloader en appuyant, à n'importe quel moment lorsque le clavier est branché, sur les combinaisons de touches Shift Gauche+Shift Droit+`B` ou Shift Gauche+Shift Droit+Escape. +Certains claviers ont des instructions spécifiques pour passer en mode bootloader. Par exemple, la touche [Bootmagic Lite]](feature_bootmagic.md#bootmagic-lite) (défaut : Échap) peut être sur une touche différente telle que Contrôle Gauche. La combinaison pour la Command (défaut : Shift Gauche+Shift Droit) peut être différente, par exemple Contrôle Gauche+Contrôle Droit. Référez-vous au fichier README de votre clavier. + +Pour mettre un clavier en mode bootloader avec USBaspLoader, appuyez sur le bouton `RESET` tout en maintenant le bouton `BOOT`. Vous pouvez aussi maintenir le bouton `BOOT` en branchant le câble USB. + +Zadig détectera automatiquement les périphériques en mode bootloader. Il se peut toutefois que vous deviez vérifier en passant par **Options → List All Devices**. + + + - Pour les claviers avec des MCUs Atmel AVR, le bootloader aura un nom similaire à `ATm32U4DFU`, et un Vendor ID `03EB`. + - Les bootloaders USBasp s'appelleront `USBasp`, avec un VID/PID `16C0:05DC`. + - Les claviers AVR flashé avec le bootloader QMK-DFU s'appelleront ` Bootloader` et auront aussi le VID `03EB`. + - Pour la plupart des claviers ARM, ils s'appelleront `STM32 BOOTLOADER`, et auront un VID/PID `0483:DF11`. + +!> Si Zadig affiche certains de vos périphériques avec le driver `HidUsb`, votre clavier n'est probablement pas en mode bootloader. La flèche aura une couleur orange et vous aurez un message de confirmation vous demandant de modifier un pilote système. **Ne continuez pas!** + +Si la flèche apparaît en vert, sélectionnez le driver et appuyez sur le bouton **Install Driver**. Le driver `libusb-win32` devrait normalement fonctionner pour AVR, et `WinUSB` pour ARM. Si vous avez des problèmes pour flasher la board, essayez d'installer un pilote différent de la liste. Pour flasher un périphérique USBaspLoader en ligne de commande avec msys2, le driver `libusbk` est recommandé, sinon `libusb-win32` devrait fonctionner correctement si vous utilisez QMK Toolbox pour flasher. + +![Zadig montrant un driver de bootloader installé correctement](https://i.imgur.com/b8VgXzx.png) + +Finalement, débranchez et rebranchez le clavier afin de vous assurer que le nouveau pilote a bien été chargé. Si vous utilisez QMK Toolbox pour flasher, redémarrez-le aussi, il arrive qu'il n'arrive pas à détecter le changement de driver. + +## Récupérer l'installation du mauvais périphérique + +Si vous n'arrivez plus à saisir de texte avec le clavier, il est possible que vous ayez installé le driver sur le clavier au lieu du bootloader. Vous pouvez facilement vérifier ceci dans Zadig. Un clavier fonctionnel a le pilote `HidUsb` installé sur toutes ses interfaces : + +![Un clavier fonctionnel vu par Zadig](https://i.imgur.com/Hx0E5kC.png) + +Ouvrez le Gestionnaire de périphériques et cherchez un périphérique qui ressemble à votre clavier. + +![La board avec le mauvais driver installé, dans le Gestionnaire de périphériques](https://i.imgur.com/L3wvX8f.png) + +Cliquez dessus avec le bouton droit et sélectionner **Désinstaller le périphérique**. Faites bien attention à sélectionner **Supprimer le pilote pour ce périphérique** avant de valider. + +![Le dialogue Suppression de périphérique, avec la boîte "suppression de pilote" cochée](https://i.imgur.com/aEs2RuA.png) + +Appuyez sur **Action → Analyser les changements de hardware**. A ce stade, vous devriez pouvoir saisir à nouveau. Vérifiez dans Zadig que les périphériques utilisent bien le pilote `HidUsb`. Si c'est le cas, vous avez corrigé le problème, votre clavier devrait fonctionner à nouveau ! diff --git a/fr-fr/faq.md b/fr-fr/faq.md new file mode 100644 index 00000000000..89576b3cc28 --- /dev/null +++ b/fr-fr/faq.md @@ -0,0 +1,6 @@ +# Foire Aux Questions + +* [FAQ Générale](faq_general.md) +* [Construire ou Compiler QMK](faq_build.md) +* [Débuguer et Dépanner QMK](faq_debug.md) +* [Keymap (disposition)](faq_keymap.md) diff --git a/fr-fr/faq_build.md b/fr-fr/faq_build.md new file mode 100644 index 00000000000..84d88afcd8b --- /dev/null +++ b/fr-fr/faq_build.md @@ -0,0 +1,154 @@ +# Foire aux questions sur la compilation + +Cette page couvre les questions concernant la compilation de QMK. Si vous ne l'avez pas encore fait, vous devriez lire les guides [Configuration de l'environnement de build](getting_started_build_tools.md) et [Instructions pour Make](getting_started_make_guide.md). + +## Je ne peux pas programmer sous Linux + +Vous aurez besoin des permissions appropriées pour utiliser un périphérique. Pour les utilisateurs de Linux, référez-vous aux instructions concernant les règles `udev` ci-dessous. Si `udev` vous pose des problèmes, une alternative est d'utiliser la commande `sudo`. Si vous ne connaissez pas cette commande, référez-vous à son manuel d'utilisation en utilisant `man sudo` ou [regardez cette page](https://linux.die.net/man/8/sudo). + +Un exemple utilisant `sudo`, lorsque votre contrôleur est un ATMega32u4 : + + $ sudo dfu-programmer atmega32u4 erase --force + $ sudo dfu-programmer atmega32u4 flash your.hex + $ sudo dfu-programmer atmega32u4 reset + +ou simplement : + + $ sudo make ::dfu + +Veuillez noter que lancer `make` avec `sudo` est généralement une **mauvaise** idée, et vous devriez préférer une des méthodes précédente, si possible. + +### Règles `udev` pour Linux + +Sous Linux, vous aurez besoin des permissions appropriées pour accéder au MCU (le micro-contrôleur). Vous avez le choix d'utiliser `sudo` en flashant le firmware, ou placer ces fichiers dans `/etc/udev/rules.d`. Une fois ajouté, lancez les commandes suivantes : + +```console +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +**/etc/udev/rules.d/50-atmel-dfu.rules:** +``` +# Atmel ATMega32U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff4", MODE:="0666" +# Atmel USBKEY AT90USB1287 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffb", MODE:="0666" +# Atmel ATMega32U2 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff0", MODE:="0666" +``` + +**/etc/udev/rules.d/52-tmk-keyboard.rules:** +``` +# tmk keyboard products https://github.com/tmk/tmk_keyboard +SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666" +``` + +**/etc/udev/rules.d/54-input-club-keyboard.rules:** + +``` +# Input Club keyboard bootloader +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", MODE:="0666" +``` + +**/etc/udev/rules.d/55-catalina.rules:** +``` +# ModemManager should ignore the following devices +ATTRS{idVendor}=="2a03", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="2341", ENV{ID_MM_DEVICE_IGNORE}="1" +``` + +**Note:** Le filtrage utilisant ModemManager fonctionnera uniquement si vous n'êtes pas en mode strict. Les commandes suivantes peuvent changer cette option : + +```console +sudo sed -i 's/--filter-policy=strict/--filter-policy=default/' /lib/systemd/system/ModemManager.service +sudo systemctl daemon-reload +sudo systemctl restart ModemManager +``` + +**/etc/udev/rules.d/56-dfu-util.rules:** + +``` +# stm32duino +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE:="0666" +# Generic stm32 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666" +``` + +### Le périphérique sériel n'est pas détecté en mode bootloader sous Linux + +Assurez-vous que votre kernel ait un support approprié pour votre périphérique. Si votre périphérique utilise USB ACM, par exemple pour les Pro Micro (AtMega32u4), assurez-vous d'inclure `CONFIG_USB_ACM=y`. D'autres périphériques peuvent avoir besoin de `USB_SERIAL` et de ses sous-options. + +## Périphérique inconnu pour le bootloader DFU + +Les problèmes rencontrés lorsque l'on flash des claviers sous Windows sont, la plupart du temps, dus à une installation du mauvais pilote, ou un pilote manquant. + +Relancer le script d'installation de QMK (`./util/qmk_install.sh` situé dans répertoire `qmk_firmware`sous MSYS2 ou WSL) ou réinstaller la QMK Toolbox peut résoudre le problème. Une alternative est de télécharger et lancer manuellement le package [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer). + +Si vous rencontrez toujours des problèmes, essayez de télécharger et lancer Zadig. Voir [Installation du driver du bootloader avec Zadig](driver_installation_zadig.md) pour plus d'informations. + +## USB VID et PID + +Vous pouvez utiliser l'ID de votre choix en modifier `config.h`. Il y a peu de chance de conflit avec d'autres produits. + +La plupart des boards QMK utilisent `0xFEED` comme vendor ID. Vérifiez les autres claviers pour être sûr de choisir un Product ID unique. + +Étudiez aussi ce ticket +https://github.com/tmk/tmk_keyboard/issues/150 + +Vous pouvez acheter un VID:PID unique ici. Je ne pense pas que ce soit nécessaire pour un usage personnel. +- http://www.obdev.at/products/vusb/license.html +- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 + +## BOOTLOADER_SIZE pour AVR + +Notez que la taille du bootloader pour les Teensy2.0++ est de 2048bytes. Quelques Makefiles peuvent contenir une erreur et avoir le mauvais commentaire. + +``` +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 2048 +# Atmel DFU loader 4096 (TMK Alt Controller) +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=2048 +``` + +## `avr-gcc: internal compiler error: Abort trap: 6 (program cc1)` sous MacOS + +C'est un problème de mise à jour avec brew, causée par des liens symboliques (symlinks) dont dépend avr-gcc qui sont détruits. + +La solution est de supprimer et réinstaller tous les modules affectés. + +``` +brew rm avr-gcc +brew rm dfu-programmer +brew rm dfu-util +brew rm gcc-arm-none-eabi +brew rm avrdude +brew install avr-gcc +brew install dfu-programmer +brew install dfu-util +brew install gcc-arm-none-eabi +brew install avrdude +``` + +### avr-gcc 8.1 et LUFA + +Si vous avez mis à jour votre avr-gcc au-dessus de la version 7, vous risquez de voir des erreurs impliquant LUA. Par exemple : + +`lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h:380:5: error: 'const' attribute on function returning 'void'` + +Pour le moment, vous devrez revenir à la version 7 de avr-gcc dans brew. + +``` +brew uninstall --force avr-gcc +brew install avr-gcc@8 +brew link --force avr-gcc@8 +``` + +### Je viens de flasher mon clavier et il ne fait rien/l'appui des touches n'est pas enregistré - c'est aussi un ARM(rev6 plank, clueboard 60, hs60v2, etc.) (Février 2019) + +A cause de la manière dont les EEPROM fonctionnent sur les puces ARM, les options sauvegardées peuvent ne plus être valides. Ceci affecte les calques par défaut et *peut*, sous certaines conditions que nous essayons encore de déterminer, rendre le clavier inutilisable. Réinitialiser l'EEPROM corrigera le problème. + +[Réinitialiser EEPROM sur Planck rev6](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) peut être utilisé pour forcer une réinitialisation d'EEPROM. Une fois cette image flashée, flashez à nouveau votre firmware standard. Cela devrait rétablir le fonctionnement de votre clavier. +Si bootmagic est activé dans n'importe quel forme, vous devriez être capable de faire aussi ceci (regardez [Documentation Bootmagic](feature_bootmagic.md) et les informations spécifiques à votre clavier). diff --git a/fr-fr/faq_debug.md b/fr-fr/faq_debug.md new file mode 100644 index 00000000000..9c12f2917a0 --- /dev/null +++ b/fr-fr/faq_debug.md @@ -0,0 +1,157 @@ +# FAQ Débugage + +Cette page détaille diverses questions fréquemment posées par les utilisateurs sur le dépannage de leurs claviers. + +# Console de débugage + +## `hid_listen` ne reconnaît pas de périphérique + +Lorsque la console de débugage sur votre périphérique n'est pas prêt, vous obtiendrez un message similaire : + +``` +Waiting for device:......... +``` + +Une fois le périphérique connecté, *hid_listen* le trouve et vous obtiendrez ce message : + +``` +Waiting for new device:......................... +Listening: +``` + +Si vous ne recevez pas ce message `Listening:`, essayez de compiler avec `CONSOLE_ENABLE=yes` dans le [Makefile] + +Il se peut que vous ayez besoin de certains privilèges avancés pour accéder à des périphériques sur des OS comme Linux. + +- Essayez `sudo hid_listen` + +## Ne reçoit pas de messages sur la console + +Vérifiez : + +- *hid_listen* trouve votre périphérique. Voir ci-dessus. +- Activez le débugage en appuyant sur **Magic**+d. Voir [Commandes Magic](https://github.com/tmk/tmk_keyboard#magic-commands). +- Définissez `debug_enable=true` en général dans `matrix_init()` du fichier **matrix.c**. +- Essayez d'utiliser la fonction `print` à la place du debug print. Voir **common/print.h**. +- Déconnectez tous les autres périphériques qui utilisent la fonction console. Voir [Issue #97](https://github.com/tmk/tmk_keyboard/issues/97). + +## Linux ou les systèmes UNIX nécessitent des privilèges super utilisateur + +Utilisez `sudo` pour exécuter *hid_listen* avec des privilèges étendus. + +``` +$ sudo hid_listen +``` + +Ou ajoutez une *udev rule* pour les périphériques TMK en plaçant un fichier dans le répertoire rules. Le chemin vers ce répertoire peut varier en fonction du système. + +Fichier: /etc/udev/rules.d/52-tmk-keyboard.rules(sous Ubuntu) +``` +# tmk keyboard products https://github.com/tmk/tmk_keyboard +SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666" +``` + +*** + +# Divers + +## Considérations de sécurité + +Vous ne voulez probablement pas "briquer" votre clavier, rendre impossible d'écrire un firmware dessus. Il y a quelques paramètres qui montrent ce qui est (et n'est probablement pas) trop risqué. + +- Si votre map de clavier n'inclut pas de RESET, pour entrer en mode DFU, vous devrez appuyer sur le bouton reset du PCB. Cela implique que vous devrez certainement dévisser certaines pièces de votre clavier pour y accéder. +- Modifier les fichiers tmk_core / common peut rendre le clavier inutilisable +- Si un fichier .hex trop large est la cause du problème : `make dfu` supprime le bloc puis teste la taille (il ne fait pas les choses dans le bon ordre), ce qui provoque une erreur. En résultat, le flash n’aura pas été fait et le clavier restera en mode DFU. +- Pour finir, notez que la taille maximale d'un fichier .hex sur un Plank est de 7000h (28672 decimal) + +``` +Linking: .build/planck_rev4_cbbrowne.elf [OK] +Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] + +Size after: + text data bss dec hex filename + 0 22396 0 22396 577c planck_rev4_cbbrowne.hex +``` + +- La taille du fichier ci-dessus est de 22396/577ch, ce qui est en dessous de 28672/7000h +- Tant que vous avez un fichier .hex alternatif correct, vous pouvez réessayer en le chargeant +- Certaines options que vous pouvez spécifier dans votre Makefile consomme de la mémoire supplémentaire. Faites attention aux options BOOTMAGIC_ENABLE, MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE, API_SYSEX_ENABLE. +- Les outils DFU **ne** vous permettent **pas** d'écrire dans le bootloader (à moins que vous n'ajoutiez des options spéciales), il n'y a donc peu de risque. +- Les EEPROM ont environ 100000 cycles d'écriture. Ne réécrivez pas le firmware de manière continue et répétée. Vous allez détruire définitivement l'EEPROM. + +## NKRO ne fonctionne pas + +Premièrement, vous devez compiler le firmware avec l'option de compilation `NKRO_ENABLE` dans le **Makefile**. + +Essayez la commande `Magic` **N** (`LShift+RShift+N` par défaut) si **NKRO** ne fonctionne toujours pas. Vous pouvez utiliser cette commande pour basculer temporairement entre le mode **NKRO** et **6KRO**. Sous certaines conditions, **NKRO** ne fonctionnera pas et vous devrez basculer en **6KRO**, en particulier lorsque vous êtes dans le BIOS. + +Si votre firmware est compilé avec `BOOTMAGIC_ENABLE` vous devrez l'activer avec la commande `BootMagic` **N** (`Espace+N` par défaut). Cette option est enregistrée dans l'EEPROM et sera gardé entre deux cycles de démarrage. + +https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch + +## Le TrackPoint a besoin Circuit de réinitialisation (Support de souris PS/2) + +Sans circuit de réinitialisation vous allez avoir des résultats inconsistants à cause de la mauvaise initialisation du matériel. Regardez le schéma du circuit du TPM754. + +- http://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 +- http://www.mikrocontroller.net/attachment/52583/tpm754.pdf + +## Impossible de lire la colonne de la matrice après 16 + +Utilisez `1UL<<16` à la place de `1<<16` dans `read_cols()` du fichier [matrix.h] lorsque le nombre de vos colonnes dépassent 16. + +En C, `1` implique un type [int] qui est [16 bits] pour les AVR, ce qui implique que vous ne pouvez pas décaler à gauche de plus de 15. Si vous utilisez `1<<16`, vous aurez un résultat non attendu de zéro. Vous devez donc utiliser un type [unsigned long] en utilisant `1UL`. + +http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 + +## Les touches spéciales ne fonctionnent pas (Touche Système, Touches de contrôle du son) + +Vous devez définir `EXTRAKEY_ENABLE` dans le fichier `rules.mk` pour les utiliser dans QMK. + +``` +EXTRAKEY_ENABLE = yes # Audio control and System control +``` + +## Réveiller du mode veille ne fonctionne pas + +Sous Windows, activez l'option `Permettre au périphérique de sortir l'ordinateur de veille` dans les paramètres des **Options d'alimentations** du **Gestionnaire de périphériques**. Vérifiez aussi les paramètres du BIOS. + +Appuyer sur n'importe quelle touche en mode veille devrait sortir l'ordinateur de veille. + +## Vous utilisez un Arduino ? + +**Faites attention au fait que le nommage des pin d'un Arduino diffère de la puce**. Par exemple, la pin `D0` n'est pas `PD0`. Vérifiez le circuit avec la fiche technique. + +- http://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf +- http://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf + +Les Arduino Leonardo et micro ont des **ATMega32U4** et peuvent être utilisés avec TMK, mais le bootloader Arduino peut causer des problèmes. + +## Activer JTAG + +Par défaut, le débugage des interfaces JTAG est désactivé dès que le clavier démarre. Les MCUs compatible JTAG viennent d'usine avec le fusible `JTAGEN` activé, et il prend certaines pins du MCU que la board pourrait utiliser pour la matrice, les LEDs, etc. + +Si vous voulez garder JTAG activé, ajoutez la ligne suivante à votre fichier `config.h` : + +```c +#define NO_JTAG_DISABLE +``` + +## Compatibilité USB 3 + +Il semble que certaines personnes ont eu des problèmes avec les ports USB 3, essayez un port USB 2. + +## Compatibilité Mac + +### OS X 10.11 et Hub + +https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 + +## Problème sur BIOS (UEFI) / Resume (Mise en veille et réveil) / Redémarrage + +Certaines personnes ont eu des problèmes de fonctionnement de leur clavier dans le BIOS et/ou après des redémarrages. + +Pour le moment, l'origine du problème n'est pas comprise, mais certaines options de compilation semble liées. Dans le Makefile, essayez de désactiver les options comme `CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE` et/ou d'autres. + +https://github.com/tmk/tmk_keyboard/issues/266 +https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/fr-fr/faq_general.md b/fr-fr/faq_general.md new file mode 100644 index 00000000000..b1eae6df166 --- /dev/null +++ b/fr-fr/faq_general.md @@ -0,0 +1,16 @@ +# Questions fréquemment posées + +## Qu'est-ce que QMK ? + +[QMK](https://github.com/qmk), acronyme pour Quantum Mechanical Keyboard, est un groupe de personnes qui construisent des outils pour des claviers personnalisés. Nous avons commencé par le [firmware QMK](https://github.com/qmk/qmk_firmware), un fork très modifié du firmware [TMK](https://github.com/tmk/tmk_keyboard). + +## Quelles sont les différences entre QMK et TMK ? + +TMK a été conçu et développé à l'origine par [Jun Wako](https://github.com/tmk). QMK a démarré comme étant le fork de [Jack Humbert](https://github.com/jackhumbert) pour le Planck. Au bout d'un moment, le fork de Jack a divergé de manière significative de TMK et, en 2015, Jack a décidé de le renommer QMK. + +D'un point de vue technique, QMK se base sur TMK en lui ajoutant plusieurs nouvelles fonctionnalités. +QMK a notamment augmenté le nombre de keycodes disponibles et les a utilisé pour implémenter des fonctionnalités avancées telles que `S()`, `LCTL()` et `MO()`. Vous pouvez voir une liste complète de ces keycodes dans [Keycodes] (keycodes.md). + +D'un point de vue management de projet et communauté, Hasu, sur TMK maintient tous les claviers supportés officiellement par lui-même, avec un peu de support de la communauté. Il existe ou peuvent être créées d'autres communautés maintenant des fork pour d'autres claviers. Peu de keymaps sont définies par défaut, les utilisateurs ne se partagent donc pas leurs keymaps en général. QMK encourage le partage des claviers et des keymaps à l'aide d'un dépôt géré de manière centrale, acceptant les pull requests qui suivent les standards de qualité. Ceux-ci sont surtout maitenus par la communauté, mais l'équipe de QMK aide aussi lorsque c'est nécessaire. + +Les deux approches ont leurs avantages et leurs inconvénients, et le développements de fonctionnalités intéressantes sont partagées entre TMK et QMK lorsque fait sens. diff --git a/fr-fr/faq_keymap.md b/fr-fr/faq_keymap.md new file mode 100644 index 00000000000..2cbbe930829 --- /dev/null +++ b/fr-fr/faq_keymap.md @@ -0,0 +1,161 @@ +# FAQ Keymap + +Cette page couvre les questions souvent posées à propos des keymaps. Si vous ne l'avez pas encore fait, vous devriez commencer par là [Aperçu des Keymap](keymap.md). + +## Quels Keycodes puis-je utiliser ? + +Regardez [Keycodes](keycodes.md) pour une liste des keycodes disponibles. Certains keycodes spécifiques ont des documentations plus complètes de disponible. + +Les keycodes sont définies dans [common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/keycode.h). + +## Quels sont les keycodes par défaut ? + +Il existe 3 configurations de clavier standard utilisées dans le monde: ANSI, ISO et JIS. L'Amérique du Nord utilise principalement l'ANSI, l'Europe et l'Afrique l'ISO et le Japon utilise JIS. Les autres régions utilisent généralement ANSI ou ISO. Les keycodes correspondant à ces dispositions spécifiques sont affichés ici : + + +![Keyboard Layout Image](https://i.imgur.com/5wsh5wM.png) + +## Certaines de mes touches sont permutées ou ne fonctionnent pas + +QMK possède deux fonctionnalités, Bootmagic et Command, qui vous permettent de modifier le comportement de votre clavier à la volée. Cela inclut, sans toutefois s'y limiter, l'échange de Ctrl / Majuscules, la désactivation de l'interface graphique, le basculement de Alt/Gui, le basculement de barre d'espacement arrière/barre oblique inversée, la désactivation de toutes les touches et d'autres modifications comportementales. + +Pour résoudre rapidement le problème, essayez de maintenir les touches Espace + Retour arrière enfoncées pendant que vous branchez votre clavier. Cela réinitialisera les paramètres stockés sur votre clavier, ramenant ces touches à un fonctionnement normal. Si cela ne fonctionne pas, regardez ici: + +* [Bootmagic](feature_bootmagic.md) +* [Command](feature_command.md) + +## La touche de menu ne fonctionne pas + +La touche trouvée sur la plupart des claviers modernes située entre `KC_RGUI` et` KC_RCTL` est en réalité appelée `KC_APP`. En effet, lorsque cette touche a été inventée, il existait déjà une clé nommée `MENU` dans les normes correspondantes. MS a donc choisi de l'appeler la touche` APP`. + +## `KC_SYSREQ` ne fonctionne pas + +Utilisez le keycode pour Print Screen (`KC_PSCREEN` or `KC_PSCR`) à la place de `KC_SYSREQ`. La combinaison de touche 'Alt + Print Screen' est reconnue comme 'System request'. + +Voir [issue #168](https://github.com/tmk/tmk_keyboard/issues/168) et +* http://en.wikipedia.org/wiki/Magic_SysRq_key +* http://en.wikipedia.org/wiki/System_request + +## Les touches alimentation ne fonctionnent pas + +Un peu déroutant, il y a deux codes de touche "Alimentation" dans QMK: `KC_POWER` dans la page d'utilisation du clavier / keypad, et `KC_SYSTEM_POWER` (ou `KC_PWR`) dans la page Consumer. + +Le premier n'est reconnu que sur macOS, alors que le dernier, `KC_SLEP` et `KC_WAKE` sont supportés par les trois principaux systèmes d'exploitation. Il est donc recommandé de les utiliser à la place. Sous Windows, ces touches prennent effet immédiatement, mais sur macOS, elles doivent être maintenues enfoncées jusqu'à ce qu'une boîte de dialogue apparaisse. + +## Modificateur "One Shot" + +Cette fonctionnalité permet de corriger un problème avec la touche Shift. En effet, il arrive de saisir plusieurs majuscules en ne voulant en saisir qu'une sur un mot. Ex : `CEtte` à la place de `Cette`. La fonctionnalité « One shot » shift permet de corriger ça. + +https://github.com/tmk/tmk_keyboard/issues/67 + +## Le modificateur d'un calque reste bloqué + +Les touches de modification ou les calques peuvent être bloquées si la commutation de calque n'est pas configurée correctement. +Pour les touches de modification et les actions de calque, vous devez placer `KC_TRANS` sur la même position du calque de destination afin de désenregistrer la clé de modificateur ou de revenir au calque précédent lors de la libération. + +* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching +* http://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 +* https://github.com/tmk/tmk_keyboard/issues/248 + +## Support de touche à verrouillage mécanique + +Cette fonctionnalité permet l'usage de *touches à verrouillage mécanique* comme [ces interrupteurs Alps](http://deskthority.net/wiki/Alps_SKCL_Lock). Vous pouvez l'activer en ajoutant ceci à votre `config.h` : + +``` +#define LOCKING_SUPPORT_ENABLE +#define LOCKING_RESYNC_ENABLE +``` + +Une fois la fonction activée, utilisez les keycodes `KC_LCAP`, `KC_LNUM` et `KC_LSCR` dans votre keymap. + +Des vieux claviers mécaniques ont parfois des touches à verrouillage, mais les claviers modernes n'en sont pas équipés. ***Vous n'avez pas besoin de cette fonction dans la majorité des cas et devez utiliser les keycodes `KC_CAPS`, `KC_NLCK` et `KC_SLCK`.*** + +## Ajouter des caractères spéciaux autres que ASCII comme la cédille 'Ç' + +Voir la fonctionnalité [Unicode](feature_unicode.md). + +## Touche `Fn` sur macOS + +Contrairement à la plupart des touches Fn, celle des claviers Apple a son propre code d'activation... en quelque sorte. Il remplace le sixième code d'activation dans un rapport de base 6KRO HID - de sorte qu'un clavier Apple ne contient en réalité que 5KRO. + +Il est techniquement possible de demander à QMK d’envoyer ce keycode. Cependant, cela nécessite une modification du format du rapport pour ajouter l'état de la touche Fn. +Pire encore, ce keycode n'est reconnu que si les identifiants du clavier VID et PID correspondent à ceux d'un vrai clavier Apple. Malheureusement QMK ne peut juridiquement prendre en charge cette fonctionnalité et il y a peu de chance que la situation s'améliore. + +Voir [cette issue](https://github.com/qmk/qmk_firmware/issues/2179) pour des informations détaillées. + +## Touches Media sous Mac OSX + +#### KC_MNXT et KC_MPRV ne fonctionnent pas sous Mac + +Utilisez `KC_MFFD`(`KC_MEDIA_FAST_FORWARD`) et `KC_MRWD`(`KC_MEDIA_REWIND`) à la place de `KC_MNXT` et `KC_MPRV`. +Voir https://github.com/tmk/tmk_keyboard/issues/195 + +## Touches supportées sous Mac OSX? + +Vous pouvez connaître les keycodes supportés par OSX en lisant ce code source. + +`usb_2_adb_keymap` contient les tableaux des pages Keyboard/Keypad vers les scancodes ADB (keycodes interne à OSX). + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c + +Et `IOHIDConsumer::dispatchConsumerEvent` s'occupe des utilisations Consumer page. + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp + +## Touches JIS dans Mac OSX + +Les touches de clavier spécifiques JIS comme `無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` ne sont pas reconnues par OSX. Vous pouvez utiliser **Seil** pour les activer, esssayez les options suivantes. + +* Activer la touche NFER sur clavier PC +* Activer la touche XFER sur clavier PC +* Activer la touche KATAKANA sur clavier PC + +https://pqrs.org/osx/karabiner/seil.html + +## RN-42 Bluetooth ne fonctionne pas avec Karabiner + +Karabiner - Outil de Keymapping sous Mac OSX - Ignore les entrées du module RN-42. Vous devez activer cette option pour rendre Karabiner compatible avec votre clavier. +https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 + +Plus de détails sur ce problème sur les liens suivants. +https://github.com/tmk/tmk_keyboard/issues/213 +https://github.com/tekezo/Karabiner/issues/403 + +## Esc et ` sur une touche simple. + +Cette fonctionnalité permet d'utiliser une touche à la fois comme touche Échap ou une touche `§` (En Azerty) selon le cas d’utilisation. Cela est très utile sur un clavier de petite taille. + +Voir la fonctionnalité [Grave Escape](feature_grave_esc.md). + +## Eject sur Mac OSX + +Le keycode`KC_EJCT` fonctionne sous OSX. https://github.com/tmk/tmk_keyboard/issues/250 + +Il semble que Windows 10 ignore le code et Linux/Xorg le reconnaît mais n'a pas de mapping par défaut. + +Nous ne sommes pas sûr quel keycode est utilisé pour la touche Eject sur les claviers Apple officiels. HHKB utilise `F20` pour la touche Eject (`Fn+f`) lorsqu'il est en mode Mac, mais ce n'est probablement pas la même chose que le keycode Eject d'Apple. + +## Qu'est-ce que `weak_mods` et `real_mods` dans `action_util.c` + +___TO BE IMPROVED___ + +real_mods est prévu pour retenir l'état des touches modificateur réelles/physiques, alors que weak_mods ne retient l'état que des modificateurs temporaires ou virtuels qui ne devraient pas affecter l'état des touches modificaterus réelles. + +Par exemple, disons que vous maintenez la touche physique "shift gauche" et tapez ACTION_MODS_KEY(LSHIFT, KC_A), + +en weak_mods, + +* (1) maintenir shift gauche : real_mods |= MOD_BIT(LSHIFT) +* (2) appuyer ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods |= MOD_BIT(LSHIFT) +* (3) lâcher ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods &= ~MOD_BIT(LSHIFT) +real_mods garde sur état modificateur. + +sans weak_mods, + +* (1) maintenir shift gauche : real_mods |= MOD_BIT(LSHIFT) +* (2) appuyer ACTION_MODS_KEY(LSHIFT, KC_A): real_mods |= MOD_BIT(LSHIFT) +* (3) lâcher ACTION_MODS_KEY(LSHIFT, KC_A): real_mods &= ~MOD_BIT(LSHIFT) +ici real_mods a perdu son état pour 'shift gauche physique'. + +weak_mods est ORed avec real_mods lorsque le rapport du clavier est envoyé. +https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/fr-fr/flashing.md b/fr-fr/flashing.md new file mode 100644 index 00000000000..74eae497799 --- /dev/null +++ b/fr-fr/flashing.md @@ -0,0 +1,238 @@ +# Instructions pour flasher et informations sur les bootloader + +Les claviers utilisent différents types de bootloaders et certains doivent être flashés différement. Heureusement, certains projets comme la [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) ont pour objectifs de permettre de flasher les différents bootloader sans trop se faire de soucis et ça peu importe les manières de les flasher. + +Si vous avez un bootloader sélectionné avec la variable `BOOTLOADER` dans votre fichier `rules.mk` alors QMK vas automatiquement calculer si votre fichier .hex n'est pas trop grand pour être flashé sur votre appareil, et il affichera la taille finale du firmware. Pour vérifier la taille manuellement, vous pouvez aussi compiler le firmware avec l'option `check-size`. Exemple : `make planck/rev4:default:check-size`. + +## DFU + +Le bootloader pour les processeurs Atmel DFU est fourni par défaut sur tous les processeurs atmega32u4. Celui-ci est utilisé par beaucoup de claviers plus vieux que les OLKB et Clueboard qui ont leur propre ICs sur leurs PCBs. D'autres claviers utilisent le bootloader DFU de LUFA (ou son fork QMK), notamment les nouveaux claviers OLKB. Ce dernier ajoute des fonctionnalités spécifiques sur le matériel. + +Pour vérifier la compatibilité avec le bootloader DFU, vérifiez que ce bloc de code est présent dans votre fichier `rules.mk`. Parfois il peut être inscrit `lufa-dfu` ou `qmk-dfu` à la place. + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = atmel-dfu +``` + +Méthodes de flash compatibles : + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (interface graphique recommandé) +* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` avec QMK (outil en ligne de commande recommandé) + +Ordre des actions : + +1. Pressez le keycode `RESET`, ou appuyez sur le bouton physique RESET ou alors créez un contact entre RST et GND. +2. Attendez que l'OS detecte l'appareil. +3. Éffacez la mémoire, cela peut être fait automatiquement. +4. Flasher le fichier .hex. +5. Redémarrez l'appareil en mode « application », cela peut être fait automatiquement. + +Alternativement : + + make ::dfu + +### DFU QMK + +QMK a un fork du bootloader LUFA DFU qui vous permet de faire un simple scan de la matrice pour quitter le bootloader et retourner à l'application. En même temps que le flash se produira, il est possible de faire flasher un led ou de produire un son via un haut parleur. Pour activer ces fonctionnalités, vous pouvez utiliser ce bloc dans votre fichier `config.h` (La touche permettant de quitter le bootloader a besoin d'être reliée entre les ports définis en INPUT et OUTPUT ici): + + #define QMK_ESC_OUTPUT F1 // usually COL + #define QMK_ESC_INPUT D5 // usually ROW + #define QMK_LED E6 + #define QMK_SPEAKER C6 + +Le fabricant et le nom du produit proviennent de vos définitions dans fichier `config.h`, et la chaîne de caractère « bootloader » est ajoutée au nom du produit. + +Pour génerer le bootloader, utilisez la cible `bootloader`. Exemple : `make planck/rev4:default:bootloader`. + +Pour génerer un fichier .hex prêt pour la production qui contiendra tant l'application que le bootloader, utilisez la cible `production`. Exemple : `make planck/rev4:default:production`. + +### Commandes DFU + +Il y a plusieurs commandes DFU que vous pouvez utiliser pour flasher le firmware sur un appareil DFU. + +* `:dfu` - C'est l'option normale qui attend qu'un appareil DFU soit disponible et qui flashe le firmware dès que c'est le cas. La vérification sera faite toutes les 5 secondes. +* `:dfu-ee` - Cette option flash un fichier `.eep` à la place d'un fichier `.hex`. Ce cas est plutôt rare. +* `:dfu-split-left` - Cette option flashe le firmware normal comme avec l'option (`:dfu`). Mais cela aussi flash le coté gauche du fichier EEPROM pour les claviers scindés. _C'est l'option idéale pour un clavier scindé basé sur le Elite C_ +* `:dfu-split-right` - Cette option flashe le firmware normal comme avec l'option (`:dfu`). Mais cela aussi flash le coté droite du fichier EEPROM pour les claviers scindés. _C'est l'option idéale pour un clavier scindé basé sur le Elite C_ + +## Caterina + +Les cartes arduinos et leurs clones utilisent le [bootloader Caterina](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina) (tous les claviers utilisant un Pro Micro, ou un clone). Ils utilisent aussi le protocole avr109 pour communiquer en virtuellement en série (serial en anglais). Les bootloaders comme le [A-Star](https://www.pololu.com/docs/0J61/9) sont basés sur Caterina. + +Pour vérifier la compatibilité avec un bootloader Caterina, vérifiez que ce bloc est présent dans votre fichier `rules.mk` : + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = caterina +``` + +Flashers compatibles : + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (Interface graphique recommandée) +* [avrdude](http://www.nongnu.org/avrdude/) avec avr109 / `:avrdude` (Outil en ligne de commande recommandé) +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +Séquence de flash :  + +1. Pressez la touche avec le keycode `RESET`, ou reliez les ports GND et RST. Vous n'avez que 7 secondes pour flasher une fois que l'opération a été faite. +2. Attendez que l'OS détecte l'appareil. +3. Flasher le fichier .hex. +4. Attendez que l'appareil redémarre automatiquement. + +ou, utilisez : + + make ::avrdude + +#### Commandes Caterina + +Il existe un certain nombre de commandes DFU que vous pouvez utiliser pour mettre à jour le firmware sur un périphérique DFU: + +* `: avrdude` - Il s’agit de l’option normale. Le script va attendre qu’un appareil Caterina soit disponible. Dès que c’est le cas, il flash le firmware. Il attendra de détecter un nouveau port COM pour le flasher. +* `: avrdude-loop` - Cela fonctionne de la même manière que`: avrdude`, mais une fois que chaque périphérique est flashé, il tentera de flasher à nouveau. Cela peut être utile pour flasher plusieurs claviers à la suite. _Cela implique de sortir manuellement de la boucle en appuyant sur Ctrl + C, Cmd + C ou un raccourci équivalent selon votre OS_ +* `: avrdude-split-left` - Cela fonctionne de la même manière que la fonction (`: avrdude`). Toutefois, cela permet aussi de flasher le coté gauche de l'EEPROM des claviers splittés / divisés. C'est donc la méthode recommandée pour les claviers splittés avec Pro Micro. +* `: avrdude-split-right` - Cela fonctionne de la même manière que la fonction (`: avrdude`). Toutefois, cela permet aussi de flasher le coté droite de l'EEPROM des claviers splittés / divisés. C'est donc la méthode recommandée pour les claviers splittés avec Pro Micro. + +## Halfkay + +Halfkay est un protocole ultra-simple développé par PJRC qui utilise HID et qui est fourni avec tous les Teensys après le modèle 2.0. + +Pour vérifier la compatibilité avec le booloader Halfkay, vérifiez que ce bloc est présent dans votre fichier `rules.mk` : + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = halfkay +``` + +Flasher compatibles : + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (Interface graphique recomandée) +* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) (petit utilitaire ultra simple) + [Teensy Loader en ligne de commande](https://www.pjrc.com/teensy/loader_cli.html) (Outil en ligne de commande recommandé) + +Séquence de flash : + +1. Pressez la touche du keycode `RESET`, ou reliez les ports RST et GND rapidement. Vous avez ensuite 7 secondes pour réaliser le flash. +2. Attendez que l'OS détecte l'appareil. +3. Flasher le fichier .hex. +4. Redémarrez l'appareil en mode « application ». Cela peut être fait automatiquement. + +## USBasploader + +USBasploader est un bootloader développé par matrixstorm. Il est utilisé sur des processeurs AVR non-USB comme le ATmega328P, qui fonctionne grâce à V-USB. + +Pour vérifier la compatibilité avec le booloader USBasploader, vérifiez que ce bloc est présent dans votre fichier `rules.mk` : + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = USBasp +``` + +Flashers compatibles : + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (Interface graphique recommandé) +* [avrdude](http://www.nongnu.org/avrdude/) avec le programmeur `usbasp`. +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +Séquence de flash : + +1. Pressez la touche du keycode `RESET`, ou reliez le port de boot pendant que RST et GND snt reliés. Cela doit être fait très rapidement. +2. Attendez que l'OS détecte l'appareil. +3. Flasher le fichier .hex. +4. Redémarrez l'appareil en mode « application ». Cela peut être fait automatiquement. + +## BootloadHID + +BootloadHID est un bootloader pour les microcontrôleurs AVR. L'utilitaire de téleversement ne demande pas de drivers au niveau du kernel et peut être lancé sans installer aucune DLLs. + +Pour vérifier la compatibilité avec le bootloader bootloadHID, vérifiez que ce bloc existe dans votre fichier `rules.mk` :  + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = bootloadHID +``` + +Utilitaires de flash compatibles : + +* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) (Utilitaire avec interface graphique recommandé) +* [bootloadhid Command Line](https://www.obdev.at/products/vusb/bootloadhid.html) / `:BootloadHID` avec QMK (utilitaire en ligne de commande recommandé) + +Séquence de flash + +1. Entrez dans le bootloader en utilisant l'une de ces méthodes : + * Pressez la touche du keycode `RESET` (Cela ne fonctionnera pas sur certains appareils). + * Verrouillez la touche « Salt » tout en branchant le clavier (Généralement ce principe est documenté dans le fichier readme du clavier) +2. Attendez que l'OS détecte l'appareil. +3. Flasher le fichier .hex. +4. Redémarrez l'appareil en mode « application ». Cela peut être fait automatiquement. + +Ou alors : + + make ::bootloadHID + +## STM32 + +Tous les processeurs STM32 contiennent un bootloader installé en usine qui ne peut pas être modifié ou supprimé. Certains processeurs STM32 ont des bootloaders qui ne peuvent pas être programmés par USB (ex : STM32F103) mais le processus reste le même. + +Pour le moment, aucune variable `BOOTLOADER` n'est nécessaire dans le fichier `rules.mk`. + +Flashers compatibles : + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (interface graphique recommandé) +* [dfu-util](https://github.com/Stefan-Schmidt/dfu-util) / `:dfu-util` (utilitaire en ligne de commande recommandé) + +Séquence pour flasher: + +1. Entrez dans le bootloader en utilisant l'une de ces méthodes : + * Utilisez une touche sur laquelle le keycode `RESET` (Cela peut ne pas fonctionner sur les appareils STM32F042) + * Si un circuit de réinitialisation (Reset) est présent alors utilisé le bouton qui lui est dédié. + * Autrement, vous devez réaliser une liaison entre BOOT0 et VCC (en appuyant sur le bouton ou à l'aide d'un pont) puis faire un pont entre RESET et GND et enfin relacher le pont BOOT0. +2. Attendre que l'os détecte l'appareil. +3. Flasher un fichier `.bin`.h + * Vous allez recevoir un avertissement à propos de la signature DFU. Ignorez-la. +4. Réinitialisez l'appareil en mode « application ». Cela peut être fait automatiquement. + * Si vous êtes en train de travailler en ligne de commande, par exemple avec un `make planck/rev6:default:dfu-util` alors soyez bien sur que l'argument `:leave` est passé aux arguments DFU grâce à la variable `DFU_ARGS` à l'intérieur de votre fichier `rules.mk` (Ex : `DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave`) afin que votre appareil redémarre après avoir été flashé. + +### Commandes STM32 + +Il y a différentes commandes que vous pouvez utiliser pour flasher un firmware dans un appareil STM32  : + +* `:dfu-util` - C'est l'option standard pour flasher un appareil STM32. Le script attendra qu'un bootloader STM32 soit présent. +* `:dfu-util-split-left` - Permet de flasher un firmware normalement, tout comme l'option précédente mais permet de configurer le côté gauche des paramètres EEPROM sur un clavier scindé. +* `:dfu-util-split-right` - Permet de flasher un firmware normalement, tout comme l'option précédente mais permet de configurer le côté droit des paramètres EEPROM sur un clavier scindé. +* `:st-link-cli` - Cela permet de flasher le firmware avec l'utilitaire en ligne de commande ST-LINK's plutôt que d'utiliser dfu-util. diff --git a/fr-fr/getting_started_getting_help.md b/fr-fr/getting_started_getting_help.md new file mode 100644 index 00000000000..fedb18c76c5 --- /dev/null +++ b/fr-fr/getting_started_getting_help.md @@ -0,0 +1,15 @@ +# Trouver de l'aide + +Il y a beaucoup de ressources pour trouver de l'aide avec QMK. + +## Chat temps-réel + +Vous trouverez des développeurs QMK et des utilisateurs sur notre [Serveur Discord](https://discord.gg/Uq7gcHh) principal. Il y a des canaux spécifiques dans le serveur pour discuter des firmwares, toolbox, hardware et configurateurs. + +## Sous-Reddit OLKB + +Le forum officiel de QMK est [/r/olkb](https://reddit.com/r/olkb) sur [reddit.com](https://reddit.com). + +## Tickets GitHub + +Vous pouvez ouvrir un [ticket sur GitHub](https://github.com/qmk/qmk_firmware/issues). Ceci est spécialement pratique lorsque votre problème demande une discussion sur le long terme ou un débugage. diff --git a/fr-fr/getting_started_github.md b/fr-fr/getting_started_github.md new file mode 100644 index 00000000000..76d107dfb99 --- /dev/null +++ b/fr-fr/getting_started_github.md @@ -0,0 +1,67 @@ +# Comment utiliser GitHub avec QMK + +GitHub peut être un peu compliqué pour ceux qui n'y sont pas familier. Ce guide va vous expliquer chaque étape de "fork", clone et envoi d'un pull request avec QMK. + +?> Ce guide part du principe que vous êtes suffisamment à l'aise pour envoyer commandes sur la ligne de commande et que vous avez Git installé sur votre système. + +Commencez par la [page GitHub de QMK](https://github.com/qmk/qmk_firmware), et vous verrez un bouton dans le coin en haut à droite qui indique "Fork": + +![Fork on GitHub](http://i.imgur.com/8Toomz4.jpg) + +Si vous faites partie d'une organisation, vous aurez besoin de savoir quel compte utiliser pour le fork. Dans la plupart des cas, vous voudrez créer le fork dans votre compte personnel. Une fois le fork complet (cela peut quelques fois prendre un peu de temps), appuyez sur le bouton "Clone or download": + +![Download from GitHub](http://i.imgur.com/N1NYcSz.jpg) + +Faites attention à sélectionner "HTTPS", et sélectionnez le lien et copiez-le: + +![HTTPS link](http://i.imgur.com/eGO0ohO.jpg) + +Ensuite, entrez `git clone --recurse-submodules ` dans la ligne de commande, et collez votre lien: + +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +Vous avez maintenant votre fork QMK sur votre machine locale, vous pouvez ajouter votre keymap, la compiler et la flasher sur votre board. Une fois heureux avec vos changements, vous pouvez les ajouter, commit, et pousser vers votre fork comme suit: + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +Vos changements existent maintenant dans votre fork sur GitHub. Si vous allez à cette adresse (`https://github.com//qmk_firmware`), vous pouvez créer un nouveau "Pull Request" en cliquant sur ce bouton: + +![New Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +Maintenant, vous pourrez voir exactement ce que vous avez commité. Si ça vous semble bien, vous pouvez le finaliser en cliquant sur "Create Pull Request": + +![Create Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +Une fois transmis, nous pourrons vous parler de vos changements, vous demander de faire des changements, et éventuellement de les accepter! + +Merci de contribuer à QMK :) diff --git a/fr-fr/getting_started_introduction.md b/fr-fr/getting_started_introduction.md new file mode 100644 index 00000000000..b2711a1671e --- /dev/null +++ b/fr-fr/getting_started_introduction.md @@ -0,0 +1,62 @@ +# Introduction + +Le but de cette page est d'expliquer les informations de base qui vous serons nécessaire pour travailler sur le projet QMK. Il a pour pré-requis que vous soyez familier à la navigation à l'aide d'un shell Unix, mais ne s'attend pas à ce que vous soyez familier avec C ou la compilation en utilisant make. + +## Structure de base de QMK + +QMK est un fork du projet [tmk_keyboard](https://github.com/tmk/tmk_keyboard) créé par [Jun Wako](https://github.com/tmk). Le code originel de TMK, avec quelques modifications, se trouve dans le dossier `tmk_core`. Les additions que QMK amène au projet se trouvent dans le dossier `quantum`. Les projets de clavier se trouvent dans les dossiers `handwired` et `keyboard`. + +### Structure du Userspace + +Dans le dossier `users` se trouve un répertoire pour chaque utilisateur. C'est un endroit où les utilisateurs peuvent mettre du code qui serait partagé entre plusieurs claviers. Merci de lire la documentation [Fonctionnalité Userspace](feature_userspace.md) pour plus d'information. + +### Structure du projet clavier + +Dans le dossier `keyboards`, son sous-dossier `handwired` et ses sous-dossiers pour les revendeurs et fabriquants (par exemple `clueboard`) se trouve un répertoire pour chaque projet clavier. Par exemple `qmk_firmware/keyboards/clueboard/2x1800`. + +A l'intérieur, vous trouverez la structure suivante: + +* `keymaps/`: différentes keymaps qui peuvent être compilées +* `rules.mk`: Ce fichier définit les options "make" par défaut. Ne modifiez pas ce fichier directement, utilisez à la place un `rules.mk` spécifique à la keymap. +* `config.h`: Ce fichier définit les options de compilation par défaut. Ne modifiez pas ce fichier directement, utilisez à la place un `config.h` spécifique à la keymap. +* `info.json`: Le fichier utilisé pour définir les options de layout de QMK Configurator. Voyez [Support Configurator](reference_configurator_support.md) pour plus d'information. +* `readme.md`: une brève description du clavier. +* `.h`: Ce fichier définit le layout du fichier par rapport à la matrice de commutation. +* `.c`: Ce fichier définit du code custom pour le clavier. + +Pour plus d'information sur la structure du projet, voyez [Directives clavier QMK](hardware_keyboard_guidelines.md). + +### Structure d'une Keymap + +Dans chaque dossier keymap, vous allez trouver les fichiers suivants. Seul le fichier `keymap.c` est nécessaire, et si le reste des fichiers n'existent pas, les options par défaut seront choisies. + +* `config.h`: les options de configuration de votre keymap +* `keymap.c`: tout le code de votre keymap, requis +* `rules.mk`: les features de QMK qui sont activées +* `readme.md`: une description de votre keymap, comment d'autres l'utiliseront, et des explications des fonctionnalités. Uploadez les images vers un service comme imgur. + +# Le fichier `config.h` + +Le fichier `config.h` peut être mis à 3 endroits: + +* keyboard (`/keyboards//config.h`) +* userspace (`/users//config.h`) +* keymap (`/keyboards//keymaps//config.h`) + +Le système de compilation cherche automatiquement les fichiers de configuration dans l'ordre au-dessus. Si vous souhaitez surcharger une configuration définie par un `config.h` précédent, vous devrez d'abord ajouter le code suivant. + +``` +#pragma once +``` + +Ensuite, pour surcharger l'option du fichier `config.h` précédent, vous devez `#undef` puis `#define` l'option à nouveau. + +Voici à quoi l'ensemble du code ressemble une fois regroupé: + +``` +#pragma once + +// overrides go here! +#undef MY_SETTING +#define MY_SETTING 4 +``` diff --git a/fr-fr/newbs.md b/fr-fr/newbs.md new file mode 100644 index 00000000000..13b06b429e3 --- /dev/null +++ b/fr-fr/newbs.md @@ -0,0 +1,23 @@ +# Le Guide pour débutant complet à QMK + +QMK est un firmware Open Source pour votre clavier mécanique. Vous pouvez utiliser QMK pour customiser votre clavier de manière simple et puissante. Tout le monde, du débutant complet au développeur avancé, ont utilisé avec succès QMK pour customiser leur clavier. Ce guide vous aidera à faire de même, quelles que soient vos compétences. + +Vous voulez savoir si votre clavier peut utiliser QMK? Si c'est un clavier mécanique que vous avez vous-même construit, il y a de bonnes chances que vous pouvez. Nous supportons un [grand nombre de "hobbyist boards"](http://qmk.fr/keyboards), donc même si votre clavier ne peut pas utiliser QMK, vous ne devriez pas avoir trop de problème pour en trouver un qui vous convienne. + +## Vue d'ensemble + +Il y a 7 sections principales dans ce guide: + +* [Pour débuter](fr-FR/newbs_getting_started.md) +* [Compiler votre premier firmware en utilisant la ligne de commande](fr-FR/newbs_building_firmware.md) +* [Compiler votre premier firmware en utilisant l'interface graphique en ligne](fr-FR/newbs_building_firmware_configurator.md) +* [Flasher le Firmware](fr-FR/newbs_flashing.md) +* [Test et Débuggage](fr-FR/newbs_testing_debugging.md) +* [Bonnes pratiques Git](fr-FR/newbs_best_practices.md) +* [Ressources d'apprentissage](fr-FR/newbs_learn_more_resources.md) + +Ce guide a pour but principal d'aider quelqu'un qui n'a jamais compilé de logiciel avant. Les recommandations et les choix qu'il contient vont donc dans ce sens. Il y a des méthodes alternatives pour beaucoup de ces procédures, et nous supportons la plupart de ces alternatives. Si vous avez un doute sur comment accomplir une tâche, vous pouvez [nous demander de l'aide](fr-FR/getting_started_getting_help.md). + +## Ressources additionnelles + +* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – Un blog créé par un utilisateur qui couvre les bases de l'utilisation du Firmware QMK, vue d'un point de vue d'un nouvel utilisateur (anglais). diff --git a/fr-fr/newbs_best_practices.md b/fr-fr/newbs_best_practices.md new file mode 100644 index 00000000000..ec68a5e3e52 --- /dev/null +++ b/fr-fr/newbs_best_practices.md @@ -0,0 +1,161 @@ +# Bonnes Pratiques + +## Ou, "Comment j'ai appris à ne plus m'en faire et aimer Git." + +Ce document a pour but d'apprendre aux novices les meilleures solutions pour faciliter la contribution à QMK. Nous allons étudier le processus de contribution à QMK, détaillant quelques moyens de rendre cette tâche plus simple. Nous allons faire quelques erreurs afin de vous apprendre à les résoudre. + +Ce document suppose les choses suivantes: + +1. Vous avez un compte GitHub, et avez [créé un "fork" pour le dépôt qmk_firmware](fr-FR/getting_started_github.md) avec votre compte. +2. Vous avez [configuré votre environnement de compilation](fr-FR/newbs_getting_started.md?id=environment-setup). + +## La branche master de votre fork: Mettre à jour souvent, ne jamais commit + +Il est hautement recommandé pour le développement de QMK, peu importe ce qui est fait ou où, de garder votre branche `master` à jour, mais de ne ***jamais*** commit dessus. A la place, faites tous vos changements dans une branche de développement et crééz des "pull requests" de votre branche lorsque vous développez. + +Pour réduire les chances de conflits de fusion (merge) — des cas où deux ou plus d'utilisateurs ont édité la même section d'un fichier en parallèle — gardez votre branche `master` relativement à jour et démarrez chaque nouveau développement en créant une nouvelle branche. + +### Mettre à jour votre branche master + +Pour garder votre branche `master` à jour, il est recommandé d'ajouter le dépôt du firmware QMK comme un dépôt distant (remote) dans git. pour se faire, ouvrez votre interface de ligne de commande Git et entrez: + +```bash +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +Pour vérifier que le dépôt a bien été ajouté, lancez la commande `git remote -v`, qui devrait retourner le résultat suivant: + +```bash +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +Maintenant que c'est fait, vous pouvez vérifier les mises à jour au dépôt en lançant `git fetch upstream`. Cela récupère les branches et les tags — appelé de manière générale "refs" — du dépôt QMK, qui a maintenant le surnom `upstream`. Nous pouvons maintenant comparer les données sur notre "fork" `origin` à celles contenues par QMK. + +Pour mettre à jour la branche master de votre "fork", lancez les commandes suivantes (en appuyant sur Enter après chaque ligne): + +```bash +git checkout master +git fetch upstream +git pull upstream master +git push origin master +``` + +Cela vous change la branche courante en master, synchronise les données de références du dépôt QMK vers votre ordinateur. La commande pull tire les données de références vers votre branche courante puis les y téleverse. La commande push permet de pousser la branche courante (master) vers votre fork GitHub. + +### Faire des changements + +Pour faire des changements, créez une nouvelle branche en entrant: + +```bash +git checkout -b dev_branch +git push --set-upstream origin dev_branch +``` + +Ceci crée une branche nommée `dev_branch`, bascule vers cette branche, et ensuite sauvegarde cette nouvelle branche vers votre fork. L'argument `--set-upstream` demande à git d'utiliser votre fork et la branche `dev_branch` à chaque fois que vous utilisez `git push` ou `git pull` depuis cette branche. Vous ne devez l'utiliser que pour le premier "push", après cela, vous pouvez utiliser simplement `git push` ou `git pull`, sans le reste des arguments. + +!> Avec `git push`, vous pouvez utiliser `-u` à la place de `--set-upstream` — `-u` est un alias pour `--set-upstream`. + +Vous pouvez appeler votre branche à peu près comme vous voulez, toutefois il est recommandé d'utiliser un nom qui est lié aux changements que vous allez faire. + +Par défaut, `git checkout -b` va faire de la branche actuelle la branche de base de votre nouvelle branche. Vous pouvez définir la base de votre nouvelle branche comme étant n'importe quelle branche existante qui n'est pas la courante en utilisant la commande: + +```bash +git checkout -b dev_branch master +``` + +Maintenant que vous avez une branche de développement, ouvrez votre éditeur de texte et faites vos changements. Il est recommandé de faire beaucoup de petits commits dans votre branche. Ainsi, un changement qui crée un problème peut être plus facilement retracé et annulé si nécessaire. Pour faire un changement, éditez et sauvez n'importe quel fichier qui doit être mis à jour, ajoutez les à la *zone de staging* de Git, et commitez les vers votre branche: + +```bash +git add path/to/updated_file +git commit -m "My commit message." +``` + +`git add` ajoute les fichiers qui ont été changés dans la *zone de staging* de Git, qui est sa "zone de chargement". Elle contient tous les changements qui vont être *validés* (committed) par `git commit`, qui sauvegarde les changements vers le dépôt. Utilisez des messages de validation descriptifs afin que vous puissiez savoir ce qui a changé d'un coup d'oeil. + +!> Si vous changez beaucoup de fichiers, mais tous les fichiers font partie du même changement, vous pouvez utiliser `git add .` pour ajouter tous les fichiers changés dans le répertoire courant, plutôt que d'avoir à ajouter chaque fichier individuellement. + +### Publier Vos Changements + +La dernière étape est de pousser vos changements vers votre fork. Pour ce faire, entrez `git push`. Git publie maintenant l'état courant de `dev_branch` vers votre fork. + +## Résoudre Les Conflits De Merge + +Parfois, lorsque votre travail sur une branche met beaucoup de temps à se compléter, des changements réalisés par d'autres peuvent entrer en conflit avec les changements que vous avez fait sur votre branche au moment où vous avez ouvert un pull request. Ceci est appelé un *conflit de merge*, et c'est ce qui arrive lorsque plusieurs personnes modifient les mêmes parties de mêmes fichiers. + +### Rebaser Vos Changements + +Un *rebase* est la manière pour Git de prendre les changements qui ont été faits à un point, les annuler, et les réappliquer sur un autre point. Dans le cas d'un conflit de merge, vous pouvez rebaser votre branche pour récupérer les changements qui ont été faits entre le moment où vous avez créé votre branche et le présent. + +Pour démarrer, lancez les commandes suivantes: + +```bash +git fetch upstream +git rev-list --left-right --count HEAD...upstream/master +``` + +La commande `git rev-list` retourne le nombre de commits qui diffère entre la branche courante et la branche master de QMK. Nous lançons `git fetch` en premier afin d'être sûr que les refs qui représentent l'état courant du dépôt upstream soient à jour. Le résultat de la commande `git rev-list` retourne deux nombres: + +```bash +$ git rev-list --left-right --count HEAD...upstream/master +7 35 +``` + +Le premier nombre représente combien il y a eu de commits sur la branche courante depuis qu'elle a été créée, et le second nombre est combien de commits ont été faits sur la branche `upstream/master` depuis que la branche a été créée et, ainsi, les changements qui ne sont pas enregistrés sur la branche courante. + +Maintenant que l'état actuel de la branche courante et la branche upstream sont connus, nous pouvons maintenant démarrer une opération de rebase: + +```bash +git rebase upstream/master +``` + +Ceci dit à Git d'annuler les commits de la branche courante puis de les réappliquer sur la branche master de QMK. + +```bash +$ git rebase upstream/master +First, rewinding head to replay your work on top of it... +Applying: Commit #1 +Using index info to reconstruct a base tree... +M conflicting_file_1.txt +Falling back to patching base and 3-way merge... +Auto-merging conflicting_file_1.txt +CONFLICT (content): Merge conflict in conflicting_file_1.txt +error: Failed to merge in the changes. +hint: Use 'git am --show-current-patch' to see the failed patch +Patch failed at 0001 Commit #1 + +Resolve all conflicts manually, mark them as resolved with +"git add/rm ", then run "git rebase --continue". +You can instead skip this commit: run "git rebase --skip". +To abort and get back to the state before "git rebase", run "git rebase --abort". +``` + +Ceci nous dit que nous avons un conflit de merge, et nous donne le nom du fichier en conflit. Ouvrez le fichier conflictuel dans votre éditeur de texte et, quelque part dans le fichier, vous trouverez quelque chose comme ça: + +```bash +<<<<<<< HEAD +

For help with any issues, email us at support@webhost.us.

+======= +

Need help? Email support@webhost.us.

+>>>>>>> Commit #1 +``` + +La ligne `<<<<<<< HEAD` montre le début d'un conflit de merge et la ligne `>>>>>>> Commit #1` indique la fin, avec les sections conflictuelles séparées par `=======`. La partie du côté `HEAD` vient de la version du fichier provenant de la branche master de QMK, et la partie marquée avec le numéro du commit provient de la branche courrante. + +Parce que Git suis *les changements des fichiers*, plutôt que les contenus des fichiers directement, si Git ne peut pas trouver le texte qu'il y avait dans le fichier avant que le commit soit fait, il ne saura pas comment modifier le fichier. Modifier le fichier à nouveau va résoudre le conflit. Faites votre changement, et sauvez le fichier. + +```bash +

Need help? Email support@webhost.us.

+``` + +Maintenant, lancez: + +```bash +git add conflicting_file_1.txt +git rebase --continue +``` + +Git enregistre le changement dans le fichier conflictuel, et continue à appliquer les commits depuis votre branche jusqu'à ce qu'il arrive à la fin. diff --git a/fr-fr/newbs_building_firmware.md b/fr-fr/newbs_building_firmware.md new file mode 100644 index 00000000000..81870d31e47 --- /dev/null +++ b/fr-fr/newbs_building_firmware.md @@ -0,0 +1,81 @@ +# Compiler Votre Premier Firmware + +Maintenant que vous avez configuré votre environnement de build, vous être prêts à compiler un firmware customisé. Pour cette section, nous allons utiliser trois programmes différents: votre explorateur de fichier, votre éditeur de texte et votre fenêtre de terminal. Gardez les 3 ouverts jusqu'à ce que vous ayez terminé et soyez content de votre firmware de clavier. + +Si vous avez fermé et rouvert votre fenêtre de terminal depuis le démarrage de ce guide, n'oubliez pas de `cd qmk_firmware` afin que votre terminal soit dans le bon répertoire. + +## Naviguez vers votre répertoire keymaps + +Démarrez par naviguer dans le répertoire `keymaps` de votre clavier. + +?> Si vous êtes sous macOS ou Windows, il y a des commandes que vous pouvez utiliser pour facilement ouvrir le dossier keymaps. + +?> macOS: + + open keyboards//keymaps + +?> Windows: + + start .\\keyboards\\\\keymaps + +## Créez une copie de la keymap `default` + +Une fois le dossier `keymaps` ouvert, créez une copie du répertoire `default`. Nous vous recommandons de nommer ce répertoire de la même manière que votre nom d'utilisateur GitHub. Vous pouvez aussi utiliser le nom que vous voulez, tant qu'il contient uniquement des lettres minuscules, des nombres et le caractère souligné (_). + +Afin d'automatiser ce processus, vous avez aussi l'option de lancer le script `new_keymap.sh`. + +Naviguez vers le répertoire `qmk_firmware/util` et tapez ce qui suit: + +``` +./new_keymap.sh +``` + +Par exemple, pour un utilisateur s'appeleant John, essayant de créer une nouvelle keymap pour le 1up60hse, il taperait: + +``` +./new_keymap.sh 1upkeyboards/1up60hse john +``` + +## Ouvrez `keymap.c` dans votre éditeur de texte préféré + +Ouvrez votre fichier `keymap.c`. Dans ce fichier, vous trouverez la structure qui contrôle comment votre clavier se comporte. En haut du fichier `keymap.c` il peut y avoir quelques `defines` et `enums` qui rendent la keymap plus simple à lire. Plus bas, vous trouverez une ligne telle que celle-ci: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +Cette ligne indique le début d'une liste de calques (layers). En dessous, vous trouverez des lignes contenant soit `LAYOUT`, soit `KEYMAP` et ces lignes indiquent le début d'un calque. En dessous de cette ligne se trouve la liste des touches qui comprennent ce calque particulier. + +!> Lorsque vous éditez votre fichier keymap, faites attention à ne pas ajouter ou enlever une virgule. Si vous le faites, vous aller empêcher votre firmware de compiler et il ne sera pas facile de trouver où la virgule est manquante ou en trop. + +## Customisez le layout à votre goût + +Libre à vous de choisir comment compléter cette étape. Faites le petit changement qui vous dérange ou retravaillez tout de zéro. Vous pouvez supprimer des calques si vous ne les utilisez pas tous, ou ajouter des calques jusqu'à un maximum de 32. Vérifiez la documentation suivante pour trouver ce que vous pouvez définir ici: + +* [Keycodes](keycodes.md) +* [Fonctionnalités](features.md) +* [FAQ](faq.md) + +?> Lorsque vous découvrez comment des keymaps fonctionnent, faites de petits changements. De gros changements rendent le débuggage des problèmes éventuels plus difficile. + +## Compilez votre firmware + +Lorsque les changements de votre keymap sont complets, vous allez devoir compiler le firmware. Pour ce faire, retournez à votre terminal et lancez la commande de compilation: + + make : + +Par exemple, si votre keymap s'appelle "xyverz" et vous compilez une keymap pour une plank rev5, vous allez utiliser cette commande: + + make planck/rev5:xyverz + +Durant la compilation, vous allez avoir beaucoup de messages sur l'écran vous informant de quels fichiers sont en train d'être compilés. Il devrait se terminer avec des messages qui ressemblent comme suit: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex [OK] + * File size is fine - 18392/28672 +``` + +## Flasher votre firmware + +Allez sur la page [Flasher le firmware](fr-FR/newbs_flashing.md) pour apprendre comment écrire votre nouveau firmware sur votre clavier. diff --git a/fr-fr/newbs_building_firmware_configurator.md b/fr-fr/newbs_building_firmware_configurator.md new file mode 100644 index 00000000000..d06242f3927 --- /dev/null +++ b/fr-fr/newbs_building_firmware_configurator.md @@ -0,0 +1,105 @@ +# Configurateur de QMK + +Le [Configurateur de QMK](https://config.qmk.fm) est une interface graphique en ligne permettant de générer des fichiers "hex" du firmware de QMK. + +?> **S'il vous plaît, suivez les étapes suivantes dans l'ordre.** + +Regardez le [Tutoriel vidéo](https://youtu.be/tx54jkRC9ZY)https://www.youtube.com/watch?v=-imgglzDMdY) + +Le configurateur de QMK fonctionne mieux avec Chrome et Firefox. + +!> **Les fichiers d'autres outils, tels que KLE ou kbfirmware ne seront pas compatibles avec le configurateur QMK. Ne les chargez pas, ne les importez pas. Le configurateur QMK est un outil DIFFERENT.** + +## Sélectionner votre clavier + +Cliquez la boîte déroulante et sélectionnez le clavier pour lequel vous voulez créer une keymap. + +?> Si votre clavier a plusieurs versions, faites attention à utiliser la bonne. + +Je vais le répéter, parce que c'est important + +!> **FAITES ATTENTION A UTILISER LA BONNE VERSION !** + +Si votre clavier est annoncé comme fonctionnant grâce à QMK mais n'est pas dans la liste, il y a des chances que le développeur ne l'ait pas encore fait, ou que nous n'avons pas encore eu le temps de le merger. Ajoutez un problème (issue) sur [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) demandant le support de votre clavier, s'il n'y a pas de [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) ouvert pour lui. Il y a aussi des claviers alimentés par QMK qui sont sur le compte GitHub du fabricant, il est bon de le vérifier aussi. + +## Sélectionner la disposition de votre clavier + +Choisissez la disposition (layout) qui représente le mieux la keymap que vous voulez créer. Certains claviers n'ont pas encore assez de dispositions ou des dispositions incorrectes. Ils seront supportés dans le future. + +## Nom de la Keymap + +Appelez cette keymap comme vous voulez. + +?> Si vous rencontrez des problèmes lors de la compilation, il peut être utile de changer ce nom, il peut déjà exister dans le dépôt du firmware QMK. + +## Créer votre keymap + +Entrer un keycode peut s'accomplir de 3 façons différentes. + +1. Glisser déposer +2. Cliquer sur un endroit vide sur le layout et cliquer sur le keycode souhaité +3. Cliquer sur un endroit vide sur le layout et appuyer sur une touche physique de votre clavier. + +Passez votre souris au dessus d'une touche et un affichage vous dira quel est le rôle du keycode. Pour une version plus verbeuse suivre: + +[Référence Keycode basique](https://docs.qmk.fm/#/keycodes_basic) +[Référence Keycode avancé](https://docs.qmk.fm/#/feature_advanced_keycodes) + +Dans le cas où vous ne trouvez pas une disposition qui supporte votre keymap, par exemple trois places pour une barre d'espace, ou deux places pour retour clavier, ou deux places pour shift, etc. etc. remplissez les TOUTES. + +### Exemples + +3 places pour la barre d'espace: Remplissez les TOUTES avec la barre d'espace + +2 places pour un retour clavier: Remplissez les DEUX avec un retour clavier + +2 places pour un shift droit: Remplissez les DEUX avec un shift droit + +1 place pour un shift gauche et 1 place pour le support ISO: Remplissez les deux avec un shift gauche + +5 places, mais seulement 4 touches: Deviner et vérifier, ou demander à quelqu'un qui l'a déjà fait. + +## Sauvez votre keymap pour des éditions futures + +Une fois satisfait de votre keymap, ou si vous souhaitez revenir travailler dessus plus tard, appuyez sur le bouton `Export Keymap`. Il vous permettra de sauvegarder votre keymap avec le nom choisi au dessus suivi de .json. + +Vous pouvez ensuite charger ce fichier .json à nouveau en appuxant sur le bouton `Import Keymap`. + +!> **ATTENTION** Ce n'est pas le même type de fichier .json utilisé pour kbfirmware.com ou n'importe quel autre outil. Si vous essayez d'utiliser ce fichier pour d'autres outil, ou le fichier .json d'autres outils avec le configurateur QMK, il y a des chances que votre clavier **explose**. + +## Générer votre fichier firmware + +Appuyez sur le bouton `Compile`. + +Une fois la compilation terminée, vous pourrez appuyer sur le bouton vert `Download Firmware`. + +## Ecrire votre firmware sur votre clavier + +Merci de vous référer à [Flasher le Firmware](fr-FR/newbs_flashing.md) + +## Dépannage + +#### Mon fichier json ne fonctionne pas + +Si le fichier .json a été généré par le configurateur QMK, bravo vous avez trouvé un bug. Merci d'ouvrir une issue sur [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) + +Sinon... vous avez raté mon message écris en gras qui dit de ne pas utiliser d'autres fichiers .json? + +#### Il y a des espaces en trop dans mon alyout? Qu'est-ce que je fais? + +Si vous voulez dire que vous avez trois places pour une barre d'espace, le mieux est de les remplir tous avec une barre d'espace. Vous pouvez faire de même avec les retour clavier et les shift. + +#### C'est quoi le keycode pour ....... + +Merci de regarder + +[Référence keycode basique](https://docs.qmk.fm/#/keycodes_basic) +[Référence keycode avancé](https://docs.qmk.fm/#/feature_advanced_keycodes) + +#### Ca ne compile pas? + +Merci de vérifier les autres dispositions de votre keymap afin d'être sûr qu'il n'y a pas de touches aléatoires. + +## Problèmes et Bugs + +Nous acceptons toujours les demandes des clients et les rapports de bugs. Merci de les remplirs sur [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) diff --git a/fr-fr/newbs_flashing.md b/fr-fr/newbs_flashing.md new file mode 100644 index 00000000000..c9849eb1048 --- /dev/null +++ b/fr-fr/newbs_flashing.md @@ -0,0 +1,367 @@ +# Flasher votre clavier + +Maintenant que vous avez compilé un firmware custom, vous allez vouloir le flasher dans votre clavier. + +## Flasher votre clavier avec QMK Toolbox + +La manière la plus simple de flasher votre clavier est avec [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases). + +Toutefois, la QMK Toolbox n'est actuellement disponible que pour Windows et macOS. Si vous utilisez Linux (ou préférez flasher le firmware depuis la ligne de commande), vous devrez utiliser [la métode décrite ci-dessous](newbs_flashing.md#flash-your-keyboard-from-the-command-line). + +### Charger le fichier dans QMK Toolbox + +Démarrez en ouvrant l'application QMK Toolbox. Cherchez le fichier de firmware dans Finder ou Explorer. Vore firmware de clavier peut être dans un de deux formats `.hex` ou `.bin`. QMK essaye de copier le bon format pour votre clavier du répertoire racine `qmk_firmware`. + +?> Si vous êtes sous Windows ou macOS il y a des commandes que vous pouvez utiliser pour facilement ouvrir le répertoire firmware dans Explorer ou Finder. + +?> Windows: + + start . + +?> macOS: + + open . + +Le fichier firmware suit toujours ce format de nommage: + + _.{bin,hex} + +Par exemple, le `plank/rev5` avec une keymap `default` aura ce nom de fichier: + + planck_rev5_default.hex + +Une fois que vous aurez trouvé votre fichier de firmware, glissez le dans la boîte "Local file" sur QMK Toolbox, ou cliquez sur "Open" et naviguez où votre firmware est enregistré. + +### Mettez votre clavier en mode DFU (Bootloader) + +Afin de flasher votre firmware custom, vous devez mettre votre clavier dans un mode spécial. Lorsqu'il sera dans ce mode, vous ne pourrez pas taper ou utiliser votre clavier. Il est très important que vous ne débranchiez pas votre clavier ou n'arrêtiez pas le processus d'écriture du firmware. + +Chaque clavier a une manière différente d'entrer dans ce mode spécial. Si votre clavier tourne actuellement QMK ou TMK et vous n'avez pas reçu d'instruction spécifiques, essayez, dans cet ordre: + +* Enfoncez les deux touches shift et appuyez sur `Pause` +* Enfoncez les deux touches shift et appuyez sur `B` +* Débranchez votre clavier, gardez shift la barre d'espace et `B` en même temps, branchez votre clavier et attendez une seconde avant de relâcher les touches. +* Appuyez la touche physique `RESET` en bas du PCB +* Trouvez les pins sur le PCB marquées `BOOT0` ou `RESET`, court circuitez ces pins en branchant votre PCB + +Lorsque vous aurez réussi, vous verrez le message suivant dans QMK Toolbox: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +``` + +### Flasher votre clavier + +Appuyez sur le boutton `Flash` dans QMK Toolbox. Vous verrez un résultat similaire à ce qui suit: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset + +*** DFU device disconnected +*** Clueboard - Clueboard 66% HotSwap connected -- 0xC1ED:0x2390 +``` + +## Flashez votre clavier à l'aide de la ligne de commande + +C'est désormais relativement simple. Lorsque vous êtes prêt à compiler et à flasher votre firmware, ouvrez la fenêtre de votre terminal et exécutez la commande de build : + + make ::flash + +Par exemple, si votre keymap s'appelle "xyverz" et que vous fabriquez une keymap pour un clavier `planck` de version `rev5` vous devrez utiliser cette commande: + + make planck/rev5:xyverz:flash + +La commande va vérifier la configuration du clavier, puis tentera de le flasher en fonction du bootloader (chargeur d’amorçage) spécifié. Cela signifie que vous n'avez pas besoin de savoir quel bootloader votre clavier utilise. Exécutez simplement la commande et laissez-le faire le gros du travail. + +Cependant, tout dépend du bootloader qui est installé sur le clavier. Si cette information n’est pas configurée ou si vous tentez de flasher un clavier qui ne permet pas d’être flashé alors vous obtiendrez cette erreur : + + WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. + +Dans ce cas, vous devrez choisir le bootloader. + +Il y a cinq bootloaders principaux. Les Pro-Micro et les clones utilisent Caterina, les Teensy utilisent Halfkay, les claviers AVR d’OLKB utilisent QMK-DFU, certains controleurs atmega32u4 utilisent DFU et la plupart des controlleurs ARM utilisent ARM DFU. + +Vous pouvez trouver plus d'information à propos des bootloaders sur la page [Instructions de flash et information sur le Bootloader](flashing.md). + +Si vous savez quel bootloader vous utilisez, lorsque vous compilez le firmware, vous pouvez ajouter quelques options à la commande `make` pour automatiser le processus de flash. + +### DFU + +Pour le bootloader DFU, lorsque vous êtes prêts à compiler et flasher votre firmware, ouvrez votre fenêtre de terminal et lancez la commande de compilation: + + make ::dfu + +Par exemple, si vous keymap s'appelle "xyverz" et vous compilez une keymap pour une plank rev5, vous utiliserez cette commande: + + make planck/rev5:xyverz:dfu + +Une fois la compilation terminée, le résultat devrait être le suivant: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex + * File size is fine - 18574/28672 + ``` + +Une fois arrivé à ce stade, le script de compilation va chercher le bootloader DFU toutes les 5 secondes. Il va répéter les messages suivants jusqu'à ce que l'appareil soit trouvé ou que vous l'annuliez. + + dfu-programmer: no device present. + Error: Bootloader not found. Trying again in 5s. + +Une fois terminé, vous devrez mettre à zéro le contrôleur. Vous allez voir un résultat similaire à ceci: + +``` +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset +``` + +?> Si vous avez des soucis concernant ceci - par exemple `dfu-programmer: no device present` - merci de regarder [Foires Aux Questions de Compilation](faq_build.md). + +#### Commandes DFU + +Il y aun certain nombre de commandes du DFU que vous pouvez utiliser pour flasher un firmware sur un device DFU: + +* `:dfu` - C'est l'option standard qui attends jusqu'à e qu'un appareil DFU soit disponible, puis flash le firmware. Il va vérifier toutes les 5 secondes, afin de voir si un appareil DFU est apparu. +* `:dfu-ee` - Ceci flash un fichier `eep` à la place du standard hex, peu commun. +* `:dfu-split-left` - Ceci flash le firmware standard, comme la commande standard (`:dfu`). Toutefois, elle flash aussi les fichiers EEPROM du "côté gauche" pour les claviers scindés. _C'est l'option idéale pour les claviers scindés basés sur Elite C._ +* `:dfu-split-right` - Ceci flash le firmware standard, comme la commande standard (`:dfu`). Toutefois, elle flash aussi les fichiers EEPROM du "côté droit" pour les claviers scindés. _C'est l'option idéale pour les claviers scindés basés sur Elite C._ + +### Caterina + +Pour les boards Arduino et leurs clones (tel que le SparkFun ProMicro), lorsque vous êtes prêt à compiler et flasher votre firmware, ouvrez votre terminal et lancer la commande de compilation: + + make ::avrdude + +Par exemple, si votre keymap se nomme "xyverz" et que vous compilez une keymap pour un Lets Split rev2, vous utiliserez la commande suivante: + + make lets_split/rev2:xyverz:avrdude + +Une fois le firmware compilé, vous aurez le résultat suivant: + +``` +Linking: .build/lets_split_rev2_xyverz.elf [OK] +Creating load file for flashing: .build/lets_split_rev2_xyverz.hex [OK] +Checking file size of lets_split_rev2_xyverz.hex [OK] + * File size is fine - 27938/28672 +Detecting USB port, reset your controller now.............. +``` + +Une fois ceci fait, réinitialisez votre board et le script va détecter et flasher le firmware. La sortie devrait ressembler à quelque chose comme ça: + +``` +Detected controller on USB port at /dev/ttyS15 + +Connecting to programmer: . +Found programmer: Id = "CATERIN"; type = S + Software Version = 1.0; No Hardware Version given. +Programmer supports auto addr increment. +Programmer supports buffered memory access with buffersize=128 bytes. + +Programmer supports the following devices: + Device code: 0x44 + +avrdude.exe: AVR device initialized and ready to accept instructions + +Reading | ################################################## | 100% 0.00s + +avrdude.exe: Device signature = 0x1e9587 (probably m32u4) +avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed + To disable this feature, specify the -D option. +avrdude.exe: erasing chip +avrdude.exe: reading input file "./.build/lets_split_rev2_xyverz.hex" +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: writing flash (27938 bytes): + +Writing | ################################################## | 100% 2.40s + +avrdude.exe: 27938 bytes of flash written +avrdude.exe: verifying flash memory against ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: load data flash data from input file ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex contains 27938 bytes +avrdude.exe: reading on-chip flash data: + +Reading | ################################################## | 100% 0.43s + +avrdude.exe: verifying ... +avrdude.exe: 27938 bytes of flash verified + +avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:FF) + +avrdude.exe done. Thank you. +``` + +Si vous avez un souci, essayez de faire ceci: + + sudo make ::avrdude + +#### Commandes Caterina + +Il existe un certain nombre de commandes DFU que vous pouvez utiliser pour mettre à jour le firmware sur un périphérique DFU: + +* `: avrdude` - Il s’agit de l’option normale. Elle attend qu’un appareil Caterina soit disponible, puis tente de flasher le firmware. Il attendra de détecter un autre port COM, puis il flashera à nouveau. +* `: avrdude-loop` - Cela fonctionne de la même manière que `: avrdude`, mais une fois que chaque périphérique est flashé, il tentera de flasher à nouveau. Cela peut être utile pour flasher plusieurs claviers à la suite. _Cela implique de sortir manuellement de la boucle en appuyant sur Ctrl + C, Cmd + C ou un raccourci équivalent selon votre OS_ +* `: avrdude-split-left` - Cela fonctionne de la même manière que la fonction (`: avrdude`). Toutefois, cela permet aussi de flasher le coté gauche de l'EEPROM des claviers splittés / divisés. C'est donc la méthode recommandée pour les claviers splittés avec Pro Micro. +* `: avrdude-split-right` - Cela fonctionne de la même manière que la fonction (`: avrdude`). Toutefois, cela permet aussi de flasher le coté droite de l'EEPROM des claviers splittés / divisés. C'est donc la méthode recommandée pour les claviers splittés avec Pro Micro. + +### HalfKay + +Pour les composants PJRC (les Teensy), lorsque vous êtes prêts à compiler et flasher votre firmware, ouvrez votre fenêtre de terminal et lancez la commande de compilation suivante: + + make ::teensy + +Par exemple, si vous keymap s'appelle "xyverz" et vous compilez une keymap pour un Ergodox ou un Ergodox EZ, vous utiliserez cette commande: + + make ergodox_ez:xyverz:teensy + +Une fois la compilation du firmware terminée, votre sortie devrait ressembler à ça: + +``` +Linking: .build/ergodox_ez_xyverz.elf [OK] +Creating load file for flashing: .build/ergodox_ez_xyverz.hex [OK] +Checking file size of ergodox_ez_xyverz.hex [OK] + * File size is fine - 25584/32256 + Teensy Loader, Command Line, Version 2.1 +Read "./.build/ergodox_ez_xyverz.hex": 25584 bytes, 79.3% usage +Waiting for Teensy device... + (hint: press the reset button) + ``` + +Une fois terminé, réinitialisez votre board. Une fois fait, vous verrez une sortie comme ça: + + ``` + Found HalfKay Bootloader +Read "./.build/ergodox_ez_xyverz.hex": 28532 bytes, 88.5% usage +Programming............................................................................................................................................................................ +................................................... +Booting +``` + +### STM32 (ARM) + +Pour la majorité des boards ARM (incluant les Proton C, Planck Rev 6, et Preonic Rev 3), lorsque vous êtes prêt à compiler et flasher votre firmware, ouvrez la fenêtre de terminal et lancez la commande de compilation: + + make ::dfu-util + +Par exemple, si votre keymap s'appelle "xyverz" et vous compilez une keymap pour le clavier Plank Revision 6, vous utiliserez cette commande et redémarrerez le clavier vers le bootloader (avant que la compilation soit terminée): + + make planck/rev6:xyverz:dfu-util + +Une fois le firmware compilé, il va afficher quelque chose comme ça: + +``` +Linking: .build/planck_rev6_xyverz.elf [OK] +Creating binary load file for flashing: .build/planck_rev6_xyverz.bin [OK] +Creating load file for flashing: .build/planck_rev6_xyverz.hex [OK] + +Size after: + text data bss dec hex filename + 0 41820 0 41820 a35c .build/planck_rev6_xyverz.hex + +Copying planck_rev6_xyverz.bin to qmk_firmware folder [OK] +dfu-util 0.9 + +Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. +Copyright 2010-2016 Tormod Volden and Stefan Schmidt +This program is Free Software and has ABSOLUTELY NO WARRANTY +Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ + +Invalid DFU suffix signature +A valid DFU suffix will be required in a future dfu-util release!!! +Opening DFU capable USB device... +ID 0483:df11 +Run-time device DFU version 011a +Claiming USB DFU Interface... +Setting Alternate Setting #0 ... +Determining device status: state = dfuERROR, status = 10 +dfuERROR, clearing status +Determining device status: state = dfuIDLE, status = 0 +dfuIDLE, continuing +DFU mode device DFU version 011a +Device returned transfer size 2048 +DfuSe interface name: "Internal Flash " +Downloading to address = 0x08000000, size = 41824 +Download [=========================] 100% 41824 bytes +Download done. +File downloaded successfully +Transitioning to dfuMANIFEST state +``` + +#### Commandes STM32 + +Il y aun certain nombre de commandes du DFU que vous pouvez utiliser pour flasher un firmware sur un device STM32: + +* `:dfu-util` - C'est l'option standard pour flasher un appareil STM32. Elle attendra qu'un bootloader STM32 soit présent et tentera de l’utiliser. +* `:dfu-util-left` - Ceci flasher le firmware standard, comme la commande standard (`:dfu-util`). Toutefois, elle flasher aussi les fichiers EEPROM du "côté gauche" pour les claviers scindés. +* `:dfu-util-right` - Ceci flash le firmware standard, comme la commande standard (`:dfu-util`). Toutefois, elle flash aussi les fichiers EEPROM du "côté droit" pour les claviers scindés. +* `:st-link-cli` - Cela permet de flasher le firmware avec l'utilitaire en ligne de commande ST-LINK's plutôt que d'utiliser dfu-util. + +### BootloadHID + +Pour les claviers basés sur Bootmapper Client(BMC)/bootloadHID/ATmega32A, si vous êtes prêts à compiler et flasher le firmware, ouvrez votre fenêtre de terminal et lancez la commande suivante : + + make ::bootloaderHID + +Par exemple, si votre keymap s'appelle "xyverz" et que vous compilez une keymap pour un jj40, utilisez cette commande: + + make jj40:xyverz:bootloaderHID + +Une fois le firmware compilé, vous aurez cette sortie: + +``` +Linking: .build/jj40_default.elf [OK] +Creating load file for flashing: .build/jj40_default.hex [OK] +Copying jj40_default.hex to qmk_firmware folder [OK] +Checking file size of jj40_default.hex [OK] + * The firmware size is fine - 21920/28672 (6752 bytes free) +``` + +A ce stade, le script de build va chercher le bootloader DFU toutes les 5 secondes. Il répétera l ’affichage de ce message jusqu'à ce que l’appareil soit trouvé ou que vous annuliez l'opération``` + +``` +Error opening HIDBoot device: The specified device was not found +Trying again in 5s. +``` + +Une fois ce résultat obtenu, réinitialisez le contrôleur. Le résultat suivant devrait s’afficher : + +``` +Page size = 128 (0x80) +Device size = 32768 (0x8000); 30720 bytes remaining +Uploading 22016 (0x5600) bytes starting at 0 (0x0) +0x05580 ... 0x05600 +``` + +## Faites l'essai! + +Bravo! Votre firmware customisé a été programmé sur votre clavier! + +Essayez-le et vérifiez qu'il fonctionne comme vous le souhaitez. Nous avons écrit [Tester et débugger](newbs_testing_debugging.md) pour compléter le guide du débutant, alors allez voir là-bas pour apprendre comment dépanner vos fonctionnalités custom. diff --git a/fr-fr/newbs_getting_started.md b/fr-fr/newbs_getting_started.md new file mode 100644 index 00000000000..8a8029fd145 --- /dev/null +++ b/fr-fr/newbs_getting_started.md @@ -0,0 +1,101 @@ +# Introduction + +Votre clavier d'ordinateur contient un processeur, proche de celui dans votre ordinateur. Ce processeur exécute un logiciel responsable de détecter les touches appuyées et envoie des rapports à propos de l'état du clavier lorsque les touches sont appuyées et relâchées. QMK prend le rôle de ce logiciel, détectant les appuis des boutons et passant cette information à l'ordinateur hôte. Lorsque vous construisez votre keymap customisée, vous créez l'équivalent d'un programme exécutable pour votre clavier. + +QMK essaie de rendre les choses simples faciles, et les choses difficiles possibles. Vous n'avez pas à savoir programmer pour créer des keymaps puissantes - vous devez seulement suivre quelques règles de syntaxe simples. + +# Guide de démarrage + +Avant de pouvoir construire des keymaps, vous devez installer quelques logiciels et configurer votre environnement de compilation. Ceci n'a besoin d'être fait seulement une fois, peu importe le nombre de clavier pour lesquels vous compter compiler un firmware. + +Si vous préférez une approche plus proche d'une interface graphique, considérez utiliser l'outil en ligne [QMK Configurator](https://config.qmk.fm). Référez-vous à [Construire votre premier firmware en utilisant l'interface graphique en ligne](newbs_building_firmware_configurator.md). + +## Logiciels à télécharger + +### Editeur de texte + +Vous allez avoir besoin d'un programme qui peut éditer et sauvegarder des fichiers **plain text**. Si vous êtes sur Windows, vous pouvez utiliser notepad et sur Linux vous pouvez utiliser gedit. Ces deux options sont des éditeurs de texte simples mais fonctionnels. Sur macOS, faites attention avec l'application par défaut TextEdit: elle ne sauvegardera pas les fichiers en mode "plain text" sauf si vous sélectionnez explicitement _Make Plain Text_ à partir du menu _Format_. + +Vous pouvez aussi télécharger et installer un éditeur de texte dédié comme [Sublime Text](https://www.sublimetext.com/) ou [VS Code](https://code.visualstudio.com/). C'est probablement la meilleure solution peu importe la plateforme car ce sont des programmes conçus spécifiquement pour éditer du code. + +?> Pas sûr de quel éditeur de texte utiliser? Laurence Bradford a écrit une [excellente introduction](https://learntocodewith.me/programming/basics/text-editors/) au sujet. + +### QMK Toolbox + +QMK Toolbox est un programme graphique optionnel pour Windows et macOS qui permet à la fois de programmer et débugger votre clavier customisé. Il vous sera probablement très utile pour facilement flasher votre clavier et analyser ses messages de débugage. + +[Télécharger la dernière version ici.](https://github.com/qmk/qmk_toolbox/releases/latest) + +* Pour Windows: `qmk_toolbox.exe` (portable) or `qmk_toolbox_install.exe` (installeur) +* Pour macOS: `QMK.Toolbox.app.zip` (portable) or `QMK.Toolbox.pkg` (installeur) + +## Configurez votre environnement + +Nous avons essayé de rendre QMK aussi simple que possible à configurer. Vous avez uniquement à préparer votre environnment Linux ou Unix et laisser QMK installer le reste. + +?> Si vous n'avez jamais travaillé avec la ligne de commande Linux/Unix, il y a un certain nombre de concepts basiques et de commandes que vous devriez apprendre. Ces ressources vous apprendrons suffisemment pour travailler avec QMK:
+[Commandes Linux à savoir](https://www.guru99.com/must-know-linux-commands.html)
+[Commandes Unix de base](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +Vous devez installer MSYS2 et Git. + +* Suivez les instructions d'installation sur la [page de MSYS2](http://www.msys2.org). +* Fermez tous les terminaux MSYS2 éventuellement ouverts et ouvrez un nouveau terminal MSYS2 MinGW 64-bit. +* Installez Git en lançant la commande: `pacman -S git`. + +### macOS + +Vous devez installer Homebew. Suivez les instructions sur la [page de Homebrew](https://brew.sh). + +Une fois Homebrew installé, continuez avec _Configurer QMK_. Dans cette étape, nous lancerons un script qui va installer d'autres paquets. + +### Linux + +Vous devez installer Git. Il est très probable que vous l'ayez déjà installé, mais sinon, une des commandes suivantes devrait l'installer: + +* Debian / Ubuntu / Devuan: `apt-get install git` +* Fedora / Red Hat / CentOS: `yum install git` +* Arch: `pacman -S git` + +?> Docker est aussi une option sur toutes les plateformes. [Appuyez ici pour plus de détail.](getting_started_build_tools.md#docker) + +## Configurer QMK + +Une fois votre environnement Linux/Unix configuré, vous êtes prêt à télécharger QMK. Nous allons le faire en utilisant Git pour "cloner" le dépôt de QMK. Ouvrez un terminal ou une fenêtre MSYS2 MinGW et gardez le ouvert pour le reste de ce guide. Dans ce terminal, lancez ces deux commandes: + +```shell +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +?> Si vous savez déjà [comment utiliser GitHub](getting_started_github.md), nous recommandons que vous créez et clonez votre propre fork. Si vous ne savez pas ce que cela veut dire, vous pouvez sans problème ignorer ce message. + +QMK vient avec un script pour vous aider à configurer le reste de ce que vous aurez besoin. Vous devez le lancer en tapant la ligne de commande suivante: + + util/qmk_install.sh + +## Testez votre environnement de compilation + +Maintenant que votre environnement de compilation de QMK est configuré, vous pouvez compiler un firmware pour votre clavier. Démarrez en compilant la keymap par défaut du clavier. Vous devriez pouvoir le faire avec une commande de ce format: + + make :default + +Par exemple, pour compiler un firmware pour une Clueboard 66%, vous utiliserez: + + make clueboard/66/rev3:default + +Une fois ceci fait, vous devriez avoir beaucoup d'information dans votre sortie qui devrait se terminer par quelque chose de similaire à ça: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +# Créer votre Keymap + +Vous êtes maintenant prêt à créer votre propre keymap! Passez à l'étape [Compiler votre premier firmware](newbs_building_firmware.md) pour ce faire. diff --git a/fr-fr/newbs_learn_more_resources.md b/fr-fr/newbs_learn_more_resources.md new file mode 100644 index 00000000000..01b1c9e8ebe --- /dev/null +++ b/fr-fr/newbs_learn_more_resources.md @@ -0,0 +1,14 @@ +# Ressources d'apprentissage + +Ces ressources permettent de donner aux nouveaux membres de la communauté QMK plus de compréhension aux informations données dans la documentation Newbs. + +Ressources Git: + +* [Tutoriel général](https://www.codecademy.com/learn/learn-git) +* [Jeu Git pour apprendre avec des exemples](https://learngitbranching.js.org/) +* [Des ressources Git pour en savoir plus à propos de GitHub](getting_started_github.md) +* [Des ressources Git spécifiques à QMK](contributing.md) + +Ressources sur les lignes de commande: + +* [Bon tutoriel général sur la ligne de commande](https://www.codecademy.com/learn/learn-the-command-line) diff --git a/fr-fr/newbs_testing_debugging.md b/fr-fr/newbs_testing_debugging.md new file mode 100644 index 00000000000..680d7644ed2 --- /dev/null +++ b/fr-fr/newbs_testing_debugging.md @@ -0,0 +1,102 @@ +# Test et débugage + +Une fois votre clavier configuré avec un firmware custom, vous êtes prêt à le tester. Avec un peu de chance, tout fonctionne parfaitement bien, dans le cas contraire, ce document vous aidera à trouver où se trouve le problème. + +## Tester + +Tester votre clavier est normalement assez simple. Appuyez chaque touche de votre clavier et assurez-vous qu'il envoie les touches auquel vous vous attendiez. Il existe même des programmes qui vous aideront à vérifier qu'aucune touche ne soit oubliée. + +Note: ces programmes ne sont ni fournis ni approuvés par QMK. + +* [QMK Configurator](https://config.qmk.fm/#/test/) (Web) +* [Switch Hitter](https://web.archive.org/web/20190413233743/https://elitekeyboards.com/switchhitter.php) (Windows seulement) +* [Keyboard Viewer](https://www.imore.com/how-use-keyboard-viewer-your-mac) (Mac seulement) +* [Keyboard Tester](http://www.keyboardtester.com) (Web) +* [Keyboard Checker](http://keyboardchecker.com) (Web) + +## Débuguer + +Votre clavier va envoyer des informations de débugage si vous avez `CONSOLE_ENABLE = yes` dans votre fichier `rules.mk`. Par défaut, la sortie est très limitée, mais vous pouvez activer le mode debug pour augmenter la quantité de sortie de débugage. Utilisez le keycode `DEBUG` dans votre keymap, utilisez la fonction [Commande](feature_command.md) pour activer le mode debug ou ajoutez le code suivant à votre keymap. + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + +### Débuguer avec QMK Toolbox + +Pour les plateformes compatibles, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) peut être utilisé pour afficher les messages de débugage pour votre clavier. + +### Débuguer avec hid_listen + +Vous préférez une solution basée sur le terminal? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), fourni par PJRC, peut aussi être utilisé pour afficher des messages de débugage. Des versions compilées pour Windows, Linux et MacOS sont disponibles. + + + +## Envoyer vos propres messages de débugage + +Parfois, il est utile d'afficher des messages de débugage depuis votre [code custom](custom_quantum_functions.md). Le faire est assez simple. Commencez par ajouter `print.h` au début de votre fichier: + + #include + +Une fois fait, vous pouvez utiliser les fonctions print suivantes: + +* `print("string")`: Affiche une simple chaîne de caractères. +* `uprintf("%s string", var)`: Affiche une chaîne de caractères formatée. +* `dprint("string")` Affiche une chaîne de caractère simple, mais uniquement lorsque le mode debug est activé. +* `dprintf("%s string", var)`: Affiche une chaîne de caractère formatée, mais uniquement lorsque le mode debug est activé. + +## Exemples de debugage + +Si dessous se trouve une liste d'exemples réels de débugage. Pour plus d'information, référez-vous à [Débuguer/Dépanner QMK](faq_debug.md). + +### A quelle position de la matrice se trouve cette activation de touche? + +Lors du portage ou lorsque vous essayez de diagnostiquer un problème de PCB, il est utile de savoir si une activation de touche est enregistrée correctement. Pour activer le log de ce scénario, ajoutez le code suivant à votre fichier keymaps `keymap.c`. + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // If console is enabled, it will print the matrix position and status of each key pressed +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif + return true; +} +``` + +Exemple de sortie + +```text +Waiting for device:....... +Listening: +KL: kc: 169, col: 0, row: 0, pressed: 1 +KL: kc: 169, col: 0, row: 0, pressed: 0 +KL: kc: 174, col: 1, row: 0, pressed: 1 +KL: kc: 174, col: 1, row: 0, pressed: 0 +KL: kc: 172, col: 2, row: 0, pressed: 1 +KL: kc: 172, col: 2, row: 0, pressed: 0 +``` + +### Combien de temps cela a pris pour une activation de touche? + +Lorsque vous testez des problèmes de performance, il peut être utile de savoir à quelle fréquence la matrice est scannée. Pour activer le log dans ce scénario, ajoutez la ligne suivante à votre fichier `config.h` de votre keymaps. + +```c +#define DEBUG_MATRIX_SCAN_RATE +``` + +Exemple de sortie + +```text + > matrix scan frequency: 315 + > matrix scan frequency: 313 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 +``` diff --git a/fuse.txt b/fuse.txt new file mode 100644 index 00000000000..99ddd2d1868 --- /dev/null +++ b/fuse.txt @@ -0,0 +1,50 @@ +Atmega32u4 Fuse/Lock Bits for Planck/Atomic/Preonic +========================= + + Low Fuse: 0x5E + High Fuse: 0x99 + Extended Fuse: 0xF3 + Lock Byte: 0xFF + + +ATMega168P Fuse/Lock Bits +========================= +This configuration is from usbasploader's Makefile. + + HFUSE 0xD6 + LFUSE 0xDF + EFUSE 0x00 + LOCK 0x3F(intact) + +#--------------------------------------------------------------------- +# ATMega168P +#--------------------------------------------------------------------- +# Fuse extended byte: +# 0x00 = 0 0 0 0 0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800) +# \+/ +# +------- BOOTSZ (00 = 2k bytes) +# Fuse high byte: +# 0xd6 = 1 1 0 1 0 1 1 0 +# ^ ^ ^ ^ ^ \-+-/ +# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) +# | | | | + --------- EESAVE (preserve EEPROM over chip erase) +# | | | +-------------- WDTON (if 0: watchdog always on) +# | | +---------------- SPIEN (allow serial programming) +# | +------------------ DWEN (debug wire enable) +# +-------------------- RSTDISBL (reset pin is enabled) +# Fuse low byte: +# 0xdf = 1 1 0 1 1 1 1 1 +# ^ ^ \ / \--+--/ +# | | | +------- CKSEL 3..0 (external >8M crystal) +# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) +# | +------------------ CKOUT (if 0: Clock output enabled) +# +-------------------- CKDIV8 (if 0: divide by 8) + + +# Lock Bits +# 0x3f = - - 1 1 1 1 1 1 +# \ / \-/ \-/ +# | | +----- LB 2..1 (No memory lock features enabled) +# | +--------- BLB0 2..1 (No restrictions for SPM or LPM accessing the Application section) +# +--------------- BLB1 2..1 (No restrictions for SPM or LPM accessing the Boot Loader section) + diff --git a/getting_started_docker.md b/getting_started_docker.md new file mode 100644 index 00000000000..e5309fdbbf5 --- /dev/null +++ b/getting_started_docker.md @@ -0,0 +1,47 @@ +# Docker Quick Start + +This project includes a Docker workflow that will allow you to build a new firmware for your keyboard very easily without major changes to your primary operating system. This also ensures that when you clone the project and perform a build, you have the exact same environment as anyone else and the QMK build infrastructure. This makes it much easier for people to help you troubleshoot any issues you encounter. + +## Requirements + +The main prerequisite is a working `docker` install. +* [Docker CE](https://docs.docker.com/install/#supported-platforms) + +## Usage + +Acquire a local copy of the QMK's repository (including submodules): + +```bash +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +Run the following command to build a keymap: +```bash +util/docker_build.sh : +# For example: util/docker_build.sh planck/rev6:default +``` + +This will compile the desired keyboard/keymap and leave the resulting `.hex` or `.bin` file in the QMK directory for you to flash. If `:keymap` is omitted, all keymaps are used. Note that the parameter format is the same as when building with `make`. + +There is also support for building _and_ flashing the keyboard straight from Docker by specifying the `target` as well: + +```bash +util/docker_build.sh keyboard:keymap:target +# For example: util/docker_build.sh planck/rev6:default:flash +``` + +You can also start the script without any parameters, in which case it will ask you to input the build parameters one by one, which you may find easier to use: + +```bash +util/docker_build.sh +# Reads parameters as input (leave blank for all keyboards/keymaps) +``` + +## FAQ + +### Why can't I flash on Windows/macOS + +On Windows and macOS, it requires [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) to be running. This is tedious to set up, so it's not recommended; use [QMK Toolbox](https://github.com/qmk/qmk_toolbox) instead. + +!> Docker for Windows requires [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) to be enabled. This means that it cannot work on versions of Windows which don't have Hyper-V, such as Windows 7, Windows 8 and **Windows 10 Home**. diff --git a/getting_started_github.md b/getting_started_github.md new file mode 100644 index 00000000000..ae594f68d81 --- /dev/null +++ b/getting_started_github.md @@ -0,0 +1,65 @@ +# How to Use GitHub with QMK + +GitHub can be a little tricky to those that aren't familiar with it - this guide will walk through each step of forking, cloning, and submitting a pull request with QMK. + +?> This guide assumes you're somewhat comfortable with running things at the command line, and have git installed on your system. + +Start on the [QMK GitHub page](https://github.com/qmk/qmk_firmware), and you'll see a button in the upper right that says "Fork": + +![Fork on GitHub](http://i.imgur.com/8Toomz4.jpg) + +If you're a part of an organization, you'll need to choose which account to fork it to. In most circumstances, you'll want to fork it to your personal account. Once your fork is completed (sometimes this takes a little while), click the "Clone or Download" button: + +![Download from GitHub](http://i.imgur.com/N1NYcSz.jpg) + +And be sure to select "HTTPS", and select the link and copy it: + +![HTTPS link](http://i.imgur.com/eGO0ohO.jpg) + +From here, enter `git clone --recurse-submodules ` into the command line, and then paste your link: + +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +You now have your QMK fork on your local machine, and you can add your keymap, compile it and flash it to your board. Once you're happy with your changes, you can add, commit, and push them to your fork like this: + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +Your changes now exist on your fork on GitHub - if you go back there (`https://github.com//qmk_firmware`), you can create a "New Pull Request" by clicking this button: + +![New Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +Here you'll be able to see exactly what you've committed - if it all looks good, you can finalize it by clicking "Create Pull Request": + +![Create Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +After submitting, we may talk to you about your changes, ask that you make changes, and eventually accept it! Thanks for contributing to QMK :) diff --git a/getting_started_introduction.md b/getting_started_introduction.md new file mode 100644 index 00000000000..6dc51b82b73 --- /dev/null +++ b/getting_started_introduction.md @@ -0,0 +1,60 @@ +# Introduction + +This page attempts to explain the basic information you need to know to work with the QMK project. It assumes that you are familiar with navigating a Unix shell, but does not assume you are familiar with C or with compiling using make. + +## Basic QMK Structure + +QMK is a fork of [Jun Wako](https://github.com/tmk)'s [tmk_keyboard](https://github.com/tmk/tmk_keyboard) project. The original TMK code, with modifications, can be found in the `tmk_core` folder. The QMK additions to the project may be found in the `quantum` folder. Keyboard projects may be found in the `handwired` and `keyboard` folders. + +### Userspace Structure + +Within the folder `users` is a directory for each user. This is a place for users to put code that they might use between keyboards. See the docs for [Userspace feature](feature_userspace.md) for more information. + +### Keyboard Project Structure + +Within the folder `keyboards`, its subfolder `handwired` and its vendor and manufacture subdirectories e.g. `clueboard` is a directory for each keyboard project, for example `qmk_firmware/keyboards/clueboard/2x1800`. Within it, you'll find the following structure: + +* `keymaps/`: Different keymaps that can be built +* `rules.mk`: The file that sets the default "make" options. Do not edit this file directly, instead use a keymap specific `rules.mk`. +* `config.h`: The file that sets the default compile time options. Do not edit this file directly, instead use a keymap specific `config.h`. +* `info.json`: The file used for setting layout for QMK Configurator. See [Configurator Support](reference_configurator_support.md) for more information. +* `readme.md`: A brief overview of the keyboard. +* `.h`: This file is where the keyboard layout is defined against the keyboard's switch matrix. +* `.c`: This file is where you can find custom code for the keyboard. + +For more information on project structure, see [QMK Keyboard Guidelines](hardware_keyboard_guidelines.md). + +### Keymap Structure + +In every keymap folder, the following files may be found. Only `keymap.c` is required, and if the rest of the files are not found the default options will be chosen. + +* `config.h`: the options to configure your keymap +* `keymap.c`: all of your keymap code, required +* `rules.mk`: the features of QMK that are enabled +* `readme.md`: a description of your keymap, how others might use it, and explanations of features. Please upload images to a service like imgur. + +# The `config.h` File + +There are 3 possible `config.h` locations: + +* keyboard (`/keyboards//config.h`) +* userspace (`/users//config.h`) +* keymap (`/keyboards//keymaps//config.h`) + +The build system automatically picks up the config files in the above order. If you wish to override any setting set by a previous `config.h` you will need to first include some boilerplate code for the settings you wish to change. + +``` +#pragma once +``` + +Then to override a setting from the previous `config.h` file you must `#undef` and then `#define` the setting again. + +The boilerplate code and setting look like this together: + +``` +#pragma once + +// overrides go here! +#undef MY_SETTING +#define MY_SETTING 4 +``` diff --git a/getting_started_make_guide.md b/getting_started_make_guide.md new file mode 100644 index 00000000000..a89dc73d018 --- /dev/null +++ b/getting_started_make_guide.md @@ -0,0 +1,144 @@ +# More Detailed `make` Instructions + +The full syntax of the `make` command is `::`, where: + +* `` is the path of the keyboard, for example `planck` + * Use `all` to compile all keyboards + * Specify the path to compile a revision, for example `planck/rev4` or `planck/rev3` + * If the keyboard doesn't have any folders, it can be left out + * To compile the default folder, you can leave it out +* `` is the name of the keymap, for example `algernon` + * Use `all` to compile all keymaps +* `` will be explained in more detail below. + +The `` means the following +* If no target is given, then it's the same as `all` below +* `all` compiles as many keyboard/revision/keymap combinations as specified. For example, `make planck/rev4:default` will generate a single .hex, while `make planck/rev4:all` will generate a hex for every keymap available to the planck. +* `flash`, `dfu`, `teensy`, `avrdude`, `dfu-util`, or `bootloadHID` compile and upload the firmware to the keyboard. If the compilation fails, then nothing will be uploaded. The programmer to use depends on the keyboard. For most keyboards it's `dfu`, but for ChibiOS keyboards you should use `dfu-util`, and `teensy` for standard Teensys. To find out which command you should use for your keyboard, check the keyboard specific readme. + * **Note**: some operating systems need root access for these commands to work, so in that case you need to run for example `sudo make planck/rev4:default:flash`. +* `clean`, cleans the build output folders to make sure that everything is built from scratch. Run this before normal compilation if you have some unexplainable problems. + +You can also add extra options at the end of the make command line, after the target + +* `make COLOR=false` - turns off color output +* `make SILENT=true` - turns off output besides errors/warnings +* `make VERBOSE=true` - outputs all of the gcc stuff (not interesting, unless you need to debug) +* `make EXTRAFLAGS=-E` - Preprocess the code without doing any compiling (useful if you are trying to debug #define commands) + +The make command itself also has some additional options, type `make --help` for more information. The most useful is probably `-jx`, which specifies that you want to compile using more than one CPU, the `x` represents the number of CPUs that you want to use. Setting that can greatly reduce the compile times, especially if you are compiling many keyboards/keymaps. I usually set it to one less than the number of CPUs that I have, so that I have some left for doing other things while it's compiling. Note that not all operating systems and make versions supports that option. + +Here are some examples commands + +* `make all:all` builds everything (all keyboard folders, all keymaps). Running just `make` from the `root` will also run this. +* `make ergodox_infinity:algernon:clean` will clean the build output of the Ergodox Infinity keyboard. +* `make planck/rev4:default:flash COLOR=false` builds and uploads the keymap without color output. + +## `rules.mk` Options + +Set these variables to `no` to disable them, and `yes` to enable them. + +`BOOTMAGIC_ENABLE` + +This allows you to hold a key and the salt key (space by default) and have access to a various EEPROM settings that persist over power loss. It's advised you keep this disabled, as the settings are often changed by accident, and produce confusing results that makes it difficult to debug. It's one of the more common problems encountered in help sessions. + +`MOUSEKEY_ENABLE` + +This gives you control over cursor movements and clicks via keycodes/custom functions. + +`EXTRAKEY_ENABLE` + +This allows you to use the system and audio control key codes. + +`CONSOLE_ENABLE` + +This allows you to print messages that can be read using [`hid_listen`](https://www.pjrc.com/teensy/hid_listen.html). + +By default, all debug (*dprint*) print (*print*, *xprintf*), and user print (*uprint*) messages will be enabled. This will eat up a significant portion of the flash and may make the keyboard .hex file too big to program. + +To disable debug messages (*dprint*) and reduce the .hex file size, include `#define NO_DEBUG` in your `config.h` file. + +To disable print messages (*print*, *xprintf*) and user print messages (*uprint*) and reduce the .hex file size, include `#define NO_PRINT` in your `config.h` file. + +To disable print messages (*print*, *xprintf*) and **KEEP** user print messages (*uprint*), include `#define USER_PRINT` in your `config.h` file (do not also include `#define NO_PRINT` in this case). + +To see the text, open `hid_listen` and enjoy looking at your printed messages. + +**NOTE:** Do not include *uprint* messages in anything other than your keymap code. It must not be used within the QMK system framework. Otherwise, you will bloat other people's .hex files. + +`COMMAND_ENABLE` + +This enables magic commands, typically fired with the default magic key combo `LSHIFT+RSHIFT+KEY`. Magic commands include turning on debugging messages (`MAGIC+D`) or temporarily toggling NKRO (`MAGIC+N`). + +`SLEEP_LED_ENABLE` + +Enables your LED to breath while your computer is sleeping. Timer1 is being used here. This feature is largely unused and untested, and needs updating/abstracting. + +`NKRO_ENABLE` + +This allows the keyboard to tell the host OS that up to 248 keys are held down at once (default without NKRO is 6). NKRO is off by default, even if `NKRO_ENABLE` is set. NKRO can be forced by adding `#define FORCE_NKRO` to your config.h or by binding `MAGIC_TOGGLE_NKRO` to a key and then hitting the key. + +`BACKLIGHT_ENABLE` + +This enables the in-switch LED backlighting. You can specify the backlight pin by putting this in your `config.h`: + + #define BACKLIGHT_PIN B7 + +`MIDI_ENABLE` + +This enables MIDI sending and receiving with your keyboard. To enter MIDI send mode, you can use the keycode `MI_ON`, and `MI_OFF` to turn it off. This is a largely untested feature, but more information can be found in the `quantum/quantum.c` file. + +`UNICODE_ENABLE` + +This allows you to send Unicode characters using `UC()` in your keymap. Code points up to `0x7FFF` are supported. This covers characters for most modern languages, as well as symbols, but it doesn't cover emoji. + +`UNICODEMAP_ENABLE` + +This allows you to send Unicode characters using `X()` in your keymap. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported. + +`UCIS_ENABLE` + +This allows you to send Unicode characters by inputting a mnemonic corresponding to the character you want to send. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported. + +For further details, as well as limitations, see the [Unicode page](feature_unicode.md). + +`AUDIO_ENABLE` + +This allows you output audio on the C6 pin (needs abstracting). See the [audio page](feature_audio.md) for more information. + +`FAUXCLICKY_ENABLE` + +Uses buzzer to emulate clicky switches. A cheap imitation of the Cherry blue switches. By default, uses the C6 pin, same as `AUDIO_ENABLE`. + +`VARIABLE_TRACE` + +Use this to debug changes to variable values, see the [tracing variables](unit_testing.md#tracing-variables) section of the Unit Testing page for more information. + +`API_SYSEX_ENABLE` + +This enables using the Quantum SYSEX API to send strings (somewhere?) + +`KEY_LOCK_ENABLE` + +This enables [key lock](feature_key_lock.md). + +`SPLIT_KEYBOARD` + +This enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common + +`SPLIT_TRANSPORT` + +As there is no standard split communication driver for ARM-based split keyboards yet, `SPLIT_TRANSPORT = custom` must be used for these. It will prevent the standard split keyboard communication code (which is AVR-specific) from being included, allowing a custom implementation to be used. + +`CUSTOM_MATRIX` + +Lets you replace the default matrix scanning routine with your own code. For further details, see the [Custom Matrix page](custom_matrix.md). + +`DEBOUNCE_TYPE` + +Lets you replace the default key debouncing routine with an alternative one. If `custom` you will need to provide your own implementation. + +## Customizing Makefile Options on a Per-Keymap Basis + +If your keymap directory has a file called `rules.mk` any options you set in that file will take precedence over other `rules.mk` options for your particular keyboard. + +So let's say your keyboard's `rules.mk` has `BACKLIGHT_ENABLE = yes`. You want your particular keyboard to not have the backlight, so you make a file called `rules.mk` and specify `BACKLIGHT_ENABLE = no`. diff --git a/getting_started_vagrant.md b/getting_started_vagrant.md new file mode 100644 index 00000000000..7a4541cfc63 --- /dev/null +++ b/getting_started_vagrant.md @@ -0,0 +1,56 @@ +# Vagrant Quick Start + +This project includes a `Vagrantfile` that will allow you to build a new firmware for your keyboard very easily without major changes to your primary operating system. This also ensures that when you clone the project and perform a build, you have the exact same environment as anyone else using the Vagrantfile to build. This makes it much easier for people to help you troubleshoot any issues you encounter. + +## Requirements + +Using the `Vagrantfile` in this repository requires you have [Vagrant](http://www.vagrantup.com/) as well as a supported provider installed: + +* [VirtualBox](https://www.virtualbox.org/) (Version at least 5.0.12) + * Sold as 'the most accessible platform to use Vagrant' +* [VMware Workstation](https://www.vmware.com/products/workstation) and [Vagrant VMware plugin](http://www.vagrantup.com/vmware) + * The (paid) VMware plugin requires a licensed copy of VMware Workstation/Fusion +* [Docker](https://www.docker.com/) + +Other than having Vagrant, a suitable provider installed and possibly a restart of your computer afterwards, you can simple run a 'vagrant up' anywhere inside the folder where you checked out this project and it will start an environment (either a virtual machine or container) that contains all the tools required to build this project. There is a post Vagrant startup hint that will get you off on the right foot, otherwise you can also reference the build documentation below. + +## Flashing the Firmware + +The "easy" way to flash the firmware is using a tool from your host OS: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox) (recommended) +* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) + +If you want to program via the command line you can uncomment the ['modifyvm'] lines in the Vagrantfile to enable the USB passthrough into Linux and then program using the command line tools like dfu-util/dfu-programmer or you can install the Teensy CLI version. + +## Vagrantfile Overview +The development environment is configured to run the QMK Docker image, `qmkfm/base_container`. This not only ensures predictability between systems, it also mirrors the CI environment. + +## FAQ + +### Why am I seeing issues under Virtualbox? +Certain versions of Virtualbox 5 appear to have an incompatibility with the Virtualbox extensions installed in the boxes in this Vagrantfile. If you encounter any issues with the /vagrant mount not succeeding, please upgrade your version of Virtualbox to at least 5.0.12. **Alternately, you can try running the following command:** + +```console +vagrant plugin install vagrant-vbguest +``` + +### How do I remove an existing environment? +Finished with your environment? From anywhere inside the folder where you checked out this project, Execute: + +```console +vagrant destroy +``` + +### What if I want to use Docker directly? +Want to benefit from the Vagrant workflow without a virtual machine? The Vagrantfile is configured to bypass running a virtual machine, and run the container directly. Execute the following when bringing up the environment to force the use of Docker: +```console +vagrant up --provider=docker +``` + +### How do I access the virtual machine instead of the Docker container? +Execute the following to bypass the `vagrant` user booting directly to the official qmk builder image: + +```console +vagrant ssh -c 'sudo -i' +``` diff --git a/gitbook/images/color-wheel.svg b/gitbook/images/color-wheel.svg new file mode 100644 index 00000000000..83e599477f7 --- /dev/null +++ b/gitbook/images/color-wheel.svg @@ -0,0 +1,441 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +image/svg+xmlOpenclipart diff --git a/gitbook/images/favicon.ico b/gitbook/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2b4e04abafb33adc0bdf4c8da56de2dd73cce097 GIT binary patch literal 1150 zcmb_cy>5d*40hCPSt3>H+_5_oVnOM^8}I@wS=kw~u`uu?z)P@4VnqVh?)*x~wGSOi z$k7m~Am4Y`{`~ol1Araf$0N}A3Fke)2LODLk&8T&p8$Yj?}y36^FI$k5FnR)hD%vZ z(@tbpGTdOCce<_d0$0|*N!{+EWg%aTs`#3|<2YDV7505E z_+8gwp66)W_FWy7zG<2`3n`7)6oL;P;-U>AYv`=lF{L w*0U@5^ZDaGsOC4>)*27z|8^}rmwU5@GM^FYi~WfKE^m|3Pejb0A?Gvi7u3j=jsO4v literal 0 HcmV?d00001 diff --git a/gitbook/images/favicon.png b/gitbook/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..509cebd8798b54b3b203cd3e45b0346dd795347d GIT binary patch literal 793 zcmV+!1LpjRP)g8{I#3Okck9IIj_rDcTW z<+w8Gg7SMG^Ck9pb}l5bN4yK2AQSj;GQ}7Hd<-%ovkwnm`ej9p{DGhRS#pxA$gEOC zV}&Fs^0-AUNcFhHgy?Y@X^Lk5|Mpc+40+4d?S5!@GK{xgXxxI*reS;@8b;{|tdDS! zt>otpVEA41&5GvQ2gf>`T~@T%4xDd5=Yty6qCb*V+>%JZ>j|_(pzRu(7Rx>R-RJlo z!fWzXSFpPWeRAHh^bIL>XUb$&=#&5e010qNS#tmY3ljhU3ljkVnw%H_00BKoL_t(I zjir-6Zo)7Whrf78GGyc)RPqK=5~%~Z1v4vRi@5>qz-gFz14~89kc}LGjYuGb^g1-= zPm`il{VkTC-_QR1{0w(mtya=!yq5={wSEQOfZ@-C4sC(Cwe|x*HNn1Sn!I;6Q4Q7* zAdX}5JO>~QL)PmxVHg6C=Q(j4UpH~rQH#aGbI~M8$g&K8D2f=3Mnq8rz+^HZNs=pu z^Qo@F^ie0lGkKne$nC67f~u+rf&kz5AI!e*69fTeS+)oO&{~VuTGBL?^Z6{h-A;@# zA|hgpk*ccXcs$B@JQkPhyblD2!-3gshEj^ + +| Board | Controller | # I/O | +| :------------ |:-------------:| ------:| +| [Swiss helper](https://www.reddit.com/r/MechanicalKeyboards/comments/8jg5d6/hand_wiring_this_might_help/) | ATmega32u4 | 20 | +| [Postage board](https://github.com/LifeIsOnTheWire/Postage-Board/)| ATmega32u4| 25 | +| [Postage board mini](https://geekhack.org/index.php?topic=101460.0)| ATmega32u4| 25 | + +## Wiring the matrix + +There is no one right way to do this. What you want to achieve is good connection at all of the joints planned and no unintentional shorts. + +Established materials and techniques include: + +| Technique | Examples | Pros | Cons | Image +| :-----------| :------- | :------ | :--- | :--- +| Lengths of wire with stripped segments | [Sasha Solomon's Dactyl](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) and [Cribbit's modern hand wire](https://geekhack.org/index.php?topic=87689.0) | Neat and tidy | Some effort in stripping the wire | ![Stripped wire](https://i.imgur.com/0GNIYY0.jpg) +| Short lengths of wire | [u/xicolinguada's ortho build](https://www.reddit.com/r/MechanicalKeyboards/comments/c39k4f/my_first_hand_wired_keyboard_its_not_perfect_but/) | Easier to strip the wire | More difficult to place | ![individual wire lengths](https://i.imgur.com/mBe5vkL.jpg) +| Magnet/Enamelled wire | [Brett Kosinski's handwired alpha](http://blog.b-ark.ca/Blog-2019-01-27) and [fknraiden's custom board](https://geekhack.org/index.php?topic=74223.0) | Can be directly soldered onto (insulation burns off with heat) | Appearance? | ![Magnet wire](https://i.imgur.com/b4b7KDb.jpg) +| Bending the legs of the diodes for the rows | [Matt3o's Brownfox](https://deskthority.net/viewtopic.php?f=7&t=6050) | Fewer solder joints required | Uninsulated | ![Bent diode legs](https://i.imgur.com/aTnG8TV.jpg) +| Using ridid wiring (e.g. brass tube) | [u/d_stilgar's invisible hardline](https://www.reddit.com/r/MechanicalKeyboards/comments/8aw5j2/invisible_hardline_keyboard_progress_update_april/) and [u/jonasfasler's first attempt](https://www.reddit.com/r/MechanicalKeyboards/comments/de1jyv/my_first_attempt_at_handwiring_a_keyboard/) | Very pretty | More difficult. No physical insulation | ![Hardline hand wire](https://i.imgur.com/CnASmPo.jpg) +| Bare wire with insulation added after (e.g. kapton tape) | [Matt3o's 65% on his website](https://matt3o.com/hand-wiring-a-custom-keyboard/) | Easier (no wire stripping required) | Not as attractive | ![Bare wire](https://i.imgur.com/AvXZShD.jpg) +| Copper tape | [ManuForm Dactyl](https://github.com/tshort/dactyl-keyboard) | Very easy | Only really works when your plate/case aligns with the bottom of your switches | ![Copper tape](https://i.imgur.com/RFyNMlL.jpg) + + +Note that these methods can be combined. Prepare your lengths of wire before moving on to soldering. + + +### A note on split keyboards + +If you are planning a split keyboard (e.g. Dactyl) each half will require a controller and a means of communicating between them (like a TRRS or hardwired cable). Further information can be found in the [QMK split keyboard documentation.](feature_split_keyboard.md) + + +### Soldering + +There are a lot of soldering guides and tips available elsewhere but here are some of the most useful and relevant for hand wiring: + +To ensure a strong solder joint you want a good amount of contact between the solder and the two pieces of metal you are connecting. A good way of doing this (though not required) is looping around pins or twisting wires together before applying solder. + +Looped around rod Looped diode leg + +If your diodes are on a packaging strip and need a bend in them (either the start of a loop or for connecting to its neighbour) this can easily done by bending it over something straight like the edge of a box, table, or ruler. This also helps keep track of the direction of the diode as all the bends will be on the same side. + +Bent diode legs + +If your iron has temperature control, set it to 315ºC (600ºF). + +Once heated, tin your soldering iron - this means melting a small amount of solder on the end of the iron and then quickly wiping it off on a wet sponge or wire cleaning pad, leaving a shiny silvery coating on the end which helps keep oxidisation at bay and helps solder to flow. + +When you come to apply the solder, hold the soldering iron against the two surfaces for a second to heat it, then apply a small amount of solder to join the two pieces together. Heating the surfaces ensures that the solder adheres to it and that it does not cool too quickly. + +Don't hold the iron on the solder/joint longer than necessary. Heat will be conducted through the surfaces and can damage components (melt switch housings etc.). Also, solder contains flux, which aids in ["wetting"](https://en.m.wikipedia.org/wiki/Wetting). The longer heat is applied to the solder the more flux will evaporate meaning you may end up with a bad solder joint with peaks which, apart from looking bad, may also increase the risk of electrical shorts. + +#### Soldering the Diodes + +Starting at the top-left switch, place the diode (with tweezers if you have them) on the switch so that the diode itself is vertically aligned, and the black line is facing toward you. The input lead of the diode should be touching the left contact on the switch, and the bent, output end should be facing to the right and resting on the switch there, like this: + +![soldering-diodes-01.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-01.png) + +Letting the diode rest, grab your solder, and touch both it and the soldering iron to the left contact at the same time - the rosin in the solder should make it easy for the solder to flow over both the diode and the keyswitch contact. The diode may move a little, and if it does, carefully position it back it place by grabbing the bent end of the diode - the other end will become hot very quickly. If you find that it's moving too much, using needle-nose pliers of some sort may help to keep the diode still when soldering. + +The smoke that the rosin releases is harmful, so be careful not to breath it or get it in your eyes/face. + +After soldering things in place, it may be helpful to blow on the joint to push the smoke away from your face, and cool the solder quicker. You should see the solder develop a matte (not shiny) surface as it solidifies. Keep in mind that it will still be very hot afterwards, and will take a couple minutes to be cool to touch. Blow on it will accelerate this process. + +When the first diode is complete, the next one will need to be soldered to both the keyswitch, and the previous diode at the new elbow. That will look something like this: + +![soldering-diodes-02.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-02.png) + +After completing a row, use the wire cutters to trim the excess wire from the tops of the diodes, and from the right side on the final switch. This process will need to completed for each row you have. + +When all of the diodes are completely soldered, it's a good idea to quickly inspect each one to ensure that your solder joints are solid and sturdy - repairing things after this is possible, but more difficult. + +#### Soldering the Columns + +You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch. + +If you're using stranded wire, it's probably easiest to just use a lot of small wires to connect each keyswitch along the column. It's possible to use one and melt through the insulation, but this isn't recommended, will produce even more harmful fumes, and can ruin your soldering iron. + +Before beginning to solder, it helps to have your wire pre-bent (if using single-cored), or at least have an idea of how you're going to route the column (especially if you're making a staggered board). Where you go in particular doesn't matter too much, as we'll be basing our keymap definitions on how it was wired - just make sure every key in a particular row is in a unique column, and that they're in order from left to right. + +If you're not using any insulation, you can try to keep the column wires elevated, and solder them near the tips of the keyswitch contacts - if the wires are sturdy enough, they won't short out to the row wiring an diodes. + +## Wiring up the controller + +Now that the matrix itself is complete, it's time to connect what you've done to the microcontroller board. + +Place the microcontroller where you want it to be located, give thought to mounting and case alignment. Bear in mind that the location of the USB socket can be different from the controller by using a short male to female cable if required,. + +Find the pinout/documentation for your microcontroller board ([links here](#common-microcontroller-boards)) and make a note of all the digital I/O pins on it (note that on some controllers, like the teensy, analogue I/O can double as digital) as these are the pins you want to connect your wires to. + +---- + +### Specific instructions for the Teensy 2.0 + +There are some pins on the Teensy that are special, like D6 (the LED on the chip), or some of the UART, SPI, I2C, or PWM channels, but only avoid those if you're planning something in addition to a keyboard. If you're unsure about wanting to add something later, you should have enough pins in total to avoid a couple. + +The pins you'll absolutely have to avoid, as with any controller, are: GND, VCC, AREF, and RST - all the others are usable and accessible in the firmware. + +---- + + +Cut wires to the length of the distance from the a point on each column/row to the controller. You can solder anywhere along the row, as long as it's after the diode - soldering before the diode (on the keyswitch side) will cause that row not to work. + +Ribbon cable can be used to keep this extra tidy. You may also want to consider routing the wires beneath the exisiting columns/rows. + +Ribbon Cable + +As you solder the wires to the controller make a note of which row/column is going to which pin on the controller as we'll use this data to setup the matrix when we create the firmware. + +As you move along, be sure that the controller is staying in place - recutting and soldering the wires is a pain! + + +## Getting Some Basic Firmware Set Up + +From here, you should have a working keyboard once you program a firmware. + +Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](http://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix). + +Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, and the .zip of source files can be modified for advanced functionality and compiled locally using the method described in [Building Your First Firmware](newbs_building_firmware?id=build-your-firmware). + +The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the code from your .zip file in a modern version of QMK Firmware, you'll need to open the .zip and follow these instructions: + +1. Extract the `kb` folder to `qmk_firmware/keyboards/handwired/`. +2. Open the extracted `kb` folder, then proceed to the `keymaps/default/` folder, and open `keymap.c`. +3. Locate and delete the `action_get_macro` code block: + ``` + const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + ... + return MACRO_NONE; + } + ``` +4. Save and close `keymap.c`. + +## Flashing the Firmware + +Install [QMK Toolbox](https://github.com/qmk/qmk_toolbox). + +![QMK Toolbox](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/qmk_toolbox.png "QMK Toolbox 0.0.16 on Windows 8.1") + +Under "Local File" navigate to your newly created .hex file. Under "Microcontroller", select the corresponding one for your controller board (common ones available [here](#common-microcontroller-boards)). + +Plug in your keyboard and press the reset button (or short the Reset and Ground pins if there is no button) and click the "Flash" button in QMK toolbox. + + +## Testing Your Firmware + +Use a website such as [QMK Configurator's Keyboard Tester](https://config.qmk.fm/#/test), [Keyboard Tester](https://www.keyboardtester.com/tester.html), or [Keyboard Checker](http://keyboardchecker.com/) or just open a text editor and try typing - you should get the characters that you put into your keymap. Test each key, and make a note of the ones that aren't working. Here's a quick trouble-shooting guide for non-working keys: + +1. Flip the keyboard back over and short the keyswitch's contacts with a piece wire - this will eliminate the possibility of the keyswitch being bad and needing to be replaced. +2. Check the solder points on the keyswitch - these need to be plump and whole. If you touch it with a moderate amount of force and it comes apart, it's not strong enough. +3. Check the solder joints on the diode - if the diode is loose, part of your row may register, while the other may not. +4. Check the solder joints on the columns - if your column wiring is loose, part or all of the column may not work. +5. Check the solder joints on both sides of the wires going to/from the Teensy - the wires need to be fully soldered and connect to both sides. +6. Check the `.h` file for errors and incorrectly placed `KC_NO`s - if you're unsure where they should be, instead duplicate a k*xy* variable. +7. Check to make sure you actually compiled the firmware and flashed the Teensy correctly. Unless you got error messages in the terminal, or a pop-up during flashing, you probably did everything correctly. +8. Use a multimeter to check that the switch is actually closing when actuated (completing the circuit when pressed down). + +If you've done all of these things, keep in mind that sometimes you might have had multiple things affecting the keyswitch, so it doesn't hurt to test the keyswitch by shorting it out at the end. + +## Finishing up + +Once you have confirmed that the keyboard is working, if you have used a seperate (non handwire specific) controller you will want to secure it in place. This can be done in many different ways e.g. hot glue, double sided sticky tape, 3D printed caddy, electrical tape. + +If you found this fullfilling you could experiment by adding additional features such as [in switch LEDs](https://geekhack.org/index.php?topic=94258.0), [in switch RGB](https://www.reddit.com/r/MechanicalKeyboards/comments/5s1l5u/photoskeyboard_science_i_made_a_handwired_rgb/), [RGB underglow](https://medium.com/@DavidNZ/hand-wired-custom-keyboard-cdd14429c7b3#.7a1ovebsk) or even an [OLED display!](https://www.reddit.com/r/olkb/comments/5zy7og/adding_ssd1306_oled_display_to_your_build/) + +There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](http://docs.qmk.fm) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](http://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/Uq7gcHh) for help! + +## Links to Other Guides + +- [matt3o's step by step guide (BrownFox build)](https://deskthority.net/viewtopic.php?f=7&t=6050) also his [website](https://matt3o.com/hand-wiring-a-custom-keyboard/) and [video guide](https://www.youtube.com/watch?v=LVzpsjFWPP4) +- [Cribbit's "Modern hand wiring guide - stronger, cleaner, easier"](https://geekhack.org/index.php?topic=87689.0) +- [Sasha Solomon's "Building my first Keyboard"](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) +- [RoastPotatoes' "How to hand wire a Planck"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/) +- [Masterzen's "Handwired keyboard build log"](http://www.masterzen.fr/2018/12/16/handwired-keyboard-build-log-part-1/) + + +# Legacy Content + +This page used to include more content. We have moved a section that used to be part of this page its own page. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for. + +## Preamble: How a Keyboard Matrix Works (and why we need diodes) :id=preamble-how-a-keyboard-matrix-works-and-why-we-need-diodes + +* [How a Keyboard Matrix Works](how_a_matrix_works.md) diff --git a/hardware_avr.md b/hardware_avr.md new file mode 100644 index 00000000000..2c0f2e9a1ac --- /dev/null +++ b/hardware_avr.md @@ -0,0 +1,180 @@ +# Keyboards with AVR Processors + +This page describes the support for for AVR processors in QMK. AVR processors include the atmega32u4, atmega32u2, at90usb1286, and other processors from Atmel Corporation. AVR processors are 8-bit MCUs that are designed to be easy to work with. The most common AVR processors in keyboards have on-board USB and plenty of GPIO for supporting large keyboard matrices. They are the most popular MCU for use in keyboards today. + +If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines.md) to get a sense of how keyboards fit into QMK. + +## Adding Your AVR Keyboard to QMK + +QMK has a number of features to simplify working with AVR keyboards. For most keyboards you don't have to write a single line of code. To get started, run the `util/new_keyboard.sh` script: + +``` +$ ./util/new_keyboard.sh +Generating a new QMK keyboard directory + +Keyboard Name: mycoolkb +Keyboard Type [avr]: +Your Name [John Smith]: + +Copying base template files... done +Copying avr template files... done +Renaming keyboard files... done +Replacing %KEYBOARD% with mycoolkb... done +Replacing %YOUR_NAME% with John Smith... done + +Created a new keyboard called mycoolkb. + +To start working on things, cd into keyboards/mycoolkb, +or open the directory in your favourite text editor. +``` + +This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard. + +## `readme.md` + +This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates.md#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](http://imgur.com) to host the images. + +## `.c` + +This is where all the custom logic for your keyboard goes. Many keyboards do not need to put anything at all in here. You can learn more about writing custom logic in [Custom Quantum Functions](custom_quantum_functions.md). + +## `.h` + +This is the file you define your [Layout Macro(s)](feature_layouts.md) in. At minimum you should have a `#define LAYOUT` for your keyboard that looks something like this: + +```c +#define LAYOUT( \ + k00, k01, k02, \ + k10, k11 \ +) { \ + { k00, k01, k02 }, \ + { k10, KC_NO, k11 }, \ +} +``` + +The first half of the `LAYOUT` pre-processor macro defines the physical arrangement of keys. The second half of the macro defines the matrix the switches are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix. + +Each of the `k__` variables needs to be unique, and typically they follow the format `k`. + +The physical matrix (the second half) must have a number of rows equaling `MATRIX_ROWS`, and each row must have exactly `MATRIX_COLS` elements in it. If you do not have this many physical keys you can use `KC_NO` to fill in the blank spots. + +## `config.h` + +The `config.h` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list there. For a complete overview of available options see the [Config Options](config_options.md) page. + +### Hardware Configuration + + +At the top of the `config.h` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `VENDOR_ID` as `0xFEED`. For the `PRODUCT_ID` you should pick a number that is not yet in use. + +Do change the `MANUFACTURER` and `PRODUCT` lines to accurately reflect your keyboard. + +```c +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER You +#define PRODUCT my_awesome_keyboard +``` + +?> Windows and macOS will display the `MANUFACTURER` and `PRODUCT` in the list of USB devices. `lsusb` on Linux instead takes these from the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html) by default. `lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in. + +### Keyboard Matrix Configuration + +The next section of the `config.h` file deals with your keyboard's matrix. The first thing you should set is the matrix's size. This is usually, but not always, the same number of rows and columns as the physical key arrangement. + +```c +#define MATRIX_ROWS 2 +#define MATRIX_COLS 3 +``` + +Once you've defined the size of your matrix you need to define which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins: + +```c +#define MATRIX_ROW_PINS { D0, D5 } +#define MATRIX_COL_PINS { F1, F0, B0 } +#define UNUSED_PINS +``` + +The number of `MATRIX_ROW_PINS` entries must be the same as the number you assigned to `MATRIX_ROWS`, and likewise for `MATRIX_COL_PINS` and `MATRIX_COLS`. You do not have to specify `UNUSED_PINS`, but you can if you want to document what pins are open. + +Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`. + +```c +#define DIODE_DIRECTION COL2ROW +``` + +#### Direct Pin Matrix +To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`. + +```c +// #define MATRIX_ROW_PINS { D0, D5 } +// #define MATRIX_COL_PINS { F1, F0, B0 } +#define DIRECT_PINS { \ + { F1, E6, B0, B2, B3 }, \ + { F5, F0, B1, B7, D2 }, \ + { F6, F7, C7, D5, D3 }, \ + { B5, C6, B6, NO_PIN, NO_PIN } \ +} +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +//#define DIODE_DIRECTION +``` + +### Backlight Configuration + +QMK supports backlighting on most GPIO pins. A select few of these can be driven by the MCU in hardware. For more details see the [Backlight Documentation](feature_backlight.md). + +```c +#define BACKLIGHT_PIN B7 +#define BACKLIGHT_LEVELS 3 +#define BACKLIGHT_BREATHING +#define BREATHING_PERIOD 6 +``` + +### Other Configuration Options + +There are a lot of features that can be configured or tuned in `config.h`. You should see the [Config Options](config_options.md) page for more details. + +## `rules.mk` + +You use the `rules.mk` file to tell QMK what files to build and what features to enable. If you are building around an atmega32u4 you can largely leave these defaults alone. If you are using another MCU you may have to tweak some parameters. + +### MCU Options + +These options tell the build system what CPU to build for. Be very careful if you change any of these settings, you can render your keyboard inoperable. + +```make +MCU = atmega32u4 +F_CPU = 16000000 +ARCH = AVR8 +F_USB = $(F_CPU) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT +``` + +### Bootloaders + +The bootloader is a special section of your MCU that allows you to upgrade the code stored on the MCU. Think of it like a Rescue Partition for your keyboard. + +#### Teensy Bootloader Example + +```make +BOOTLOADER = halfkay +``` + +#### Atmel DFU Loader Example + +```make +BOOTLOADER = atmel-dfu +``` + +#### Pro Micro Bootloader Example + +```make +BOOTLOADER = caterina +``` + +### Build Options + +There are a number of features that can be turned on or off in `rules.mk`. See the [Config Options](config_options.md#feature-options) page for a detailed list and description. diff --git a/hardware_drivers.md b/hardware_drivers.md new file mode 100644 index 00000000000..7e89c0d2b9a --- /dev/null +++ b/hardware_drivers.md @@ -0,0 +1,39 @@ +# QMK Hardware Drivers + +QMK is used on a lot of different hardware. While support for the most common MCU's and matrix configurations is built-in there are a number of drivers that can be added to a keyboard to support additional hardware. Examples include mice and other pointing devices, i/o expanders for split keyboards, bluetooth modules, and LCD, OLED, and TFT screens. + + + +# Available Drivers + +## ProMicro (AVR Only) + +Support for addressing pins on the ProMicro by their Arduino name rather than their AVR name. This needs to be better documented, if you are trying to do this and reading the code doesn't help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) and we can help you through the process. + +## SSD1306 OLED Driver + +Support for SSD1306 based OLED displays. For more information see the [OLED Driver Feature](feature_oled_driver.md) page. + +## uGFX + +You can make use of uGFX within QMK to drive character and graphic LCDs, LED arrays, OLED, TFT, and other display technologies. This needs to be better documented, if you are trying to do this and reading the code doesn't help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) and we can help you through the process. + +## WS2812 + +Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page. + +## IS31FL3731 + +Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. + +## IS31FL3733 + +Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. + +## 24xx series external I2C EEPROM + +Support for an external I2C-based EEPROM instead of using the on-chip EEPROM. For more information on how to setup the driver see the [EEPROM Driver](eeprom_driver.md) page. diff --git a/hardware_keyboard_guidelines.md b/hardware_keyboard_guidelines.md new file mode 100644 index 00000000000..742b56572ca --- /dev/null +++ b/hardware_keyboard_guidelines.md @@ -0,0 +1,234 @@ +# QMK Keyboard Guidelines + +Since starting, QMK has grown by leaps and bounds thanks to people like you who contribute to creating and maintaining our community keyboards. As we've grown we've discovered some patterns that work well, and ask that you conform to them to make it easier for other people to benefit from your hard work. + + +## Use QMK Lint + +We have provided a tool, `qmk lint`, which will let you check over your keyboard for problems. We suggest using it frequently while working on your keyboard and keymap. + +Example passing check: + +``` +$ qmk lint -kb rominronin/katana60/rev2 +Ψ Lint check passed! +``` + +Example failing check: + +``` +$ qmk lint -kb clueboard/66/rev3 +☒ Missing keyboards/clueboard/66/rev3/readme.md +☒ Lint check failed! +``` + +## Naming Your Keyboard/Project + +All keyboard names are in lower case, consisting only of letters, numbers, and underscore (`_`). Names may not begin with an underscore. Forward slash (`/`) is used as a sub-folder separation character. + +The names `test`, `keyboard`, and `all` are reserved for make commands and may not be used as a keyboard or subfolder name. + +Valid Examples: + +* `412_64` +* `chimera_ortho` +* `clueboard/66/rev3` +* `planck` +* `v60_type_r` + +## Sub-folders + +QMK uses sub-folders both for organization and to share code between revisions of the same keyboard. You can nest folders up to 4 levels deep: + + qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4 + +If a sub-folder has a `rules.mk` file it will be considered a compilable keyboard. It will be available in QMK Configurator and tested with `make all`. If you are using a folder to organize several keyboards from the same maker you should not have a `rules.mk` file. + +Example: + +Clueboard uses sub-folders for both purposes, organization and keyboard revisions. + +* [`qmk_firmware`](https://github.com/qmk/qmk_firmware/tree/master) + * [`keyboards`](https://github.com/qmk/qmk_firmware/tree/master/keyboards) + * [`clueboard`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard) ← This is the organization folder, there's no `rules.mk` file + * [`60`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/60) ← This is a compilable keyboard, it has a `rules.mk` file + * [`66`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66) ← This is also compilable- it uses `DEFAULT_FOLDER` to specify `rev3` as the default revision + * [`rev1`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev1) ← compilable: `make clueboard/66/rev1` + * [`rev2`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev2) ← compilable: `make clueboard/66/rev2` + * [`rev3`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev3) ← compilable: `make clueboard/66/rev3` or `make clueboard/66` + +## Keyboard Folder Structure + +Your keyboard should be located in `qmk_firmware/keyboards/` and the folder name should be your keyboard's name as described in the previous section. Inside this folder should be several files: + +* `readme.md` +* `info.json` +* `config.h` +* `rules.mk` +* `.c` +* `.h` + +### `readme.md` + +All projects need to have a `readme.md` file that explains what the keyboard is, who made it and where it's available. If applicable, it should also contain links to more information, such as the maker's website. Please follow the [published template](documentation_templates.md#keyboard-readmemd-template). + +### `info.json` + +This file is used by the [QMK API](https://github.com/qmk/qmk_api). It contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard. You can also set metadata here. For more information see the [reference page](reference_info_json.md). + +### `config.h` + +All projects need to have a `config.h` file that sets things like the matrix size, product name, USB VID/PID, description and other settings. In general, use this file to set essential information and defaults for your keyboard that will always work. + +The `config.h` files can also be placed in sub-folders, and the order in which they are read is as follows: + +* `keyboards/top_folder/config.h` + * `keyboards/top_folder/sub_1/config.h` + * `keyboards/top_folder/sub_1/sub_2/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/config.h` + * `users/a_user_folder/config.h` + * `keyboards/top_folder/keymaps/a_keymap/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/post_config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/post_config.h` + * `keyboards/top_folder/sub_1/sub_2/post_config.h` + * `keyboards/top_folder/sub_1/post_config.h` +* `keyboards/top_folder/post_config.h` + +The `post_config.h` file can be used for additional post-processing, depending on what is specified in the `config.h` file. For example, if you define the `IOS_DEVICE_ENABLE` macro in your keymap-level `config.h` file as follows, you can configure more detailed settings accordingly in the `post_config.h` file: + +* `keyboards/top_folder/keymaps/a_keymap/config.h` + ```c + #define IOS_DEVICE_ENABLE + ``` +* `keyboards/top_folder/post_config.h` + ```c + #ifndef IOS_DEVICE_ENABLE + // USB_MAX_POWER_CONSUMPTION value for this keyboard + #define USB_MAX_POWER_CONSUMPTION 400 + #else + // fix iPhone and iPad power adapter issue + // iOS device need lessthan 100 + #define USB_MAX_POWER_CONSUMPTION 100 + #endif + + #ifdef RGBLIGHT_ENABLE + #ifndef IOS_DEVICE_ENABLE + #define RGBLIGHT_LIMIT_VAL 200 + #define RGBLIGHT_VAL_STEP 17 + #else + #define RGBLIGHT_LIMIT_VAL 35 + #define RGBLIGHT_VAL_STEP 4 + #endif + #ifndef RGBLIGHT_HUE_STEP + #define RGBLIGHT_HUE_STEP 10 + #endif + #ifndef RGBLIGHT_SAT_STEP + #define RGBLIGHT_SAT_STEP 17 + #endif + #endif + ``` + +?> If you define options using `post_config.h` as in the above example, you should not define the same options in the keyboard- or user-level `config.h`. + +### `rules.mk` + +The presence of this file means that the folder is a keyboard target and can be used in `make` commands. This is where you setup the build environment for your keyboard and configure the default set of features. + +The `rules.mk` file can also be placed in a sub-folder, and its reading order is as follows: + +* `keyboards/top_folder/rules.mk` + * `keyboards/top_folder/sub_1/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/sub_3/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/rules.mk` + * `keyboards/top_folder/keymaps/a_keymap/rules.mk` + * `users/a_user_folder/rules.mk` +* `common_features.mk` + +Many of the settings written in the `rules.mk` file are interpreted by `common_features.mk`, which sets the necessary source files and compiler options. + +?> See `build_keyboard.mk` and `common_features.mk` for more details. + +### `` + +This is where you will write custom code for your keyboard. Typically you will write code to initialize and interface with the hardware in your keyboard. If your keyboard consists of only a key matrix with no LEDs, speakers, or other auxiliary hardware this file can be blank. + +The following functions are typically defined in this file: + +* `void matrix_init_kb(void)` +* `void matrix_scan_kb(void)` +* `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* `void led_set_kb(uint8_t usb_led)` + +### `` + +This file is used to define the matrix for your keyboard. You should define at least one C macro which translates an array into a matrix representing the physical switch matrix for your keyboard. If it's possible to build your keyboard with multiple layouts you should define additional macros. + +If you have only a single layout you should call this macro `LAYOUT`. + +When defining multiple layouts you should have a base layout, named `LAYOUT_all`, that supports all possible switch positions on your matrix, even if that layout is impossible to build physically. This is the macro you should use in your `default` keymap. You should then have additional keymaps named `default_` that use your other layout macros. This will make it easier for people to use the layouts you define. + +Layout macro names are entirely lowercase, except for the word `LAYOUT` at the front. + +As an example, if you have a 60% PCB that supports ANSI and ISO you might define the following layouts and keymaps: + +| Layout Name | Keymap Name | Description | +|-------------|-------------|-------------| +| LAYOUT_all | default | A layout that supports both ISO and ANSI | +| LAYOUT_ansi | default_ansi | An ANSI layout | +| LAYOUT_iso | default_iso | An ISO layout | + +## Image/Hardware Files + +In an effort to keep the repo size down we're no longer accepting binary files of any format, with few exceptions. Hosting them elsewhere (such as ) and linking them in the `readme.md` is preferred. + +Hardware files (such as plates, cases, pcb) can be contributed to the [qmk.fm repo](https://github.com/qmk/qmk.fm) and they will be made available on [qmk.fm](http://qmk.fm). Downloadable files are stored in `//` (name follows the same format as above) which are served at `http://qmk.fm//`, and pages are generated from `/_pages//` which are served at the same location (.md files are generated into .html files through Jekyll). Check out the `lets_split` folder for an example. + +## Keyboard Defaults + +Given the amount of functionality that QMK exposes it's very easy to confuse new users. When putting together the default firmware for your keyboard we recommend limiting your enabled features and options to the minimal set needed to support your hardware. Recommendations for specific features follow. + +### Bootmagic and Command + +[Bootmagic](feature_bootmagic.md) and [Command](feature_command.md) are two related features that allow a user to control their keyboard in non-obvious ways. We recommend you think long and hard about if you're going to enable either feature, and how you will expose this functionality. Keep in mind that users who want this functionality can enable it in their personal keymaps without affecting all the novice users who may be using your keyboard as their first programmable board. + +By far the most common problem new users encounter is accidentally triggering Bootmagic while they're plugging in their keyboard. They're holding the keyboard by the bottom, unknowingly pressing in alt and spacebar, and then they find that these keys have been swapped on them. We recommend leaving this feature disabled by default, but if you do turn it on consider setting `BOOTMAGIC_KEY_SALT` to a key that is hard to press while plugging your keyboard in. + +If your keyboard does not have 2 shift keys you should provide a working default for `IS_COMMAND`, even when you have set `COMMAND_ENABLE = no`. This will give your users a default to conform to if they do enable Command. + +## Custom Keyboard Programming + +As documented on [Customizing Functionality](custom_quantum_functions.md) you can define custom functions for your keyboard. Please keep in mind that your users may want to customize that behavior as well, and make it possible for them to do that. If you are providing a custom function, for example `process_record_kb()`, make sure that your function calls the `_user()` version of the call too. You should also take into account the return value of the `_user()` version, and only run your custom code if the user returns `true`. + +## Non-Production/Handwired Projects + +We're happy to accept any project that uses QMK, including prototypes and handwired ones, but we have a separate `/keyboards/handwired/` folder for them, so the main `/keyboards/` folder doesn't get overcrowded. If a prototype project becomes a production project at some point in the future, we'd be happy to move it to the main `/keyboards/` folder! + +## Warnings as Errors + +When developing your keyboard, keep in mind that all warnings will be treated as errors - these small warnings can build-up and cause larger errors down the road (and keeping them is generally a bad practice). + +## Copyright Blurb + +If you're adapting your keyboard's setup from another project, but not using the same code, be sure to update the copyright header at the top of the files to show your name, in this format: + + Copyright 2017 Your Name + +If you are modifying someone else's code and have made only trivial changes you should leave their name in the copyright statement. If you have done significant work on the file you should add your name to theirs, like so: + + Copyright 2017 Their Name Your Name + +The year should be the first year the file is created. If work was done to that file in later years you can reflect that by appending the second year to the first, like so: + + Copyright 2015-2017 Your Name + +## License + +The core of QMK is licensed under the [GNU General Public License](https://www.gnu.org/licenses/licenses.en.html). If you are shipping binaries for AVR processors you may choose either [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) or [GPLv3](https://www.gnu.org/licenses/gpl.html). If you are shipping binaries for ARM processors you must choose [GPL Version 3](https://www.gnu.org/licenses/gpl.html) to comply with the [ChibiOS](http://www.chibios.org) GPLv3 license. + +If your keyboard makes use of the [uGFX](https://ugfx.io) features within QMK you must comply with the [uGFX License](https://ugfx.io/license.html), which requires a separate commercial license before selling a device containing uGFX. + +## Technical Details + +If you're looking for more information on making your keyboard work with QMK, [check out the hardware section](hardware.md)! diff --git a/he-il/README.md b/he-il/README.md new file mode 100644 index 00000000000..c16801b2bd1 --- /dev/null +++ b/he-il/README.md @@ -0,0 +1,34 @@ +
+# קושחה עבור Quantum Mechanical Keyboard + +[![גירסה נוכחית](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![מצב הבניה](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![ערוץ דיסקורד](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![מצב מסמכים](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![תומכי GitHub](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![מזלגות GitHub](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## מה היא קושחת QMK? + +QMK (*Quantum Mechanical Keyboard*) היא קהילת קוד פתוח (open source) שמתחזקת את קושחת QMK, QMK Toolbox, qmk.fm, והמסמכים המתאימים. קושחת QMK היא קושחה עבור מקלדות המבוססת על [tmk\_keyboard](http://github.com/tmk/tmk_keyboard) עם כמה תוספות עבור בקרי Atmel AVR ובאופן ספציפי יותר - [מוצרי OLKB](http://olkb.com), מקלדת [ErgoDox EZ](http://www.ergodox-ez.com), וגם [מוצרי Clueboard](http://clueboard.co/). בנוסף, הקושחה עברה פורט עבור שבבי ARM באמצעות ChibiOS. ניתן להשתמש בה על מנת להפעיל את מקלדות ה PCB המקוסטמות שלך. + +## איך להשיג אותה + +אם אתם מתכננים לתרום מיפוי מקשים, מקלדת או יכולת ל QMK, הדבר הקל ביותר הוא [לעשות פורק לריפו בGitHub](https://github.com/qmk/qmk_firmware#fork-destination-box), ולעשות קלון לריפו בסביבה המקומית ושם לבצע את השינויים שלכם, לדחוף אותם ולפתוח [Pull Request](https://github.com/qmk/qmk_firmware/pulls) מהפורק שלך. + +אחרת, אפשר להוריד את הקושחה באופן ישיר ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), או לשכפל אותה באמצעות git (`git@github.com:qmk/qmk_firmware.git`), או https (`https://github.com/qmk/qmk_firmware.git`). + +## איך לקמפל + +לפני שתצליחו לקמפל, תדרשו [להתקין סביבה](he-il/getting_started_build_tools.md) עבור פיתוח AVR ו/או ARM. ברגע שהדבר בוצע, תוכלו להריץ פקודת `make` כדי לבנות מקלדת ומיפוי עם התחביר הבא: + + make planck/rev4:default + +כך תוכלו לבנות את גרסא `rev4` של ה `planck` עם מיפוי ברירת המחדל (`default`). לא כל המקלדות בעלות גרסאות (נקרא גם תת-פרוייקט או תיקייה), במקרה כזה, אפשר להריץ את הפקודה הבאה: + + make preonic:default + +## איך להתאים + +לQMK יש המון [יכולות](he-il/features.md) שאפשר לנווט בהן, וכמות נכבדת של [תיעוד ודוקומנטציה](http://docs.qmk.fm) בה אפשר לנבור. רוב הפיצ׳רים באים לידי ביטוי על ידי שינוי [מיפוי המקלדת](he-il/keymap.md) ושינוי [קודי המקשים](he-il/keycodes.md). +
diff --git a/he-il/_summary.md b/he-il/_summary.md new file mode 100644 index 00000000000..148eb6400d8 --- /dev/null +++ b/he-il/_summary.md @@ -0,0 +1,140 @@ +
+ +**בשפה העברית** +* [המדריך המלא למתחילים](he-il/newbs.md) + * [מקורות ללמידה](he-il/newbs_learn_more_resources.md) +* [בסיס QMK](he-il/README.md) + * [מבוא לQMK](he-il/getting_started_introduction.md) + * [איך להשתמש בGitHub](he-il/getting_started_github.md) + * [קבלת עזרה](he-il/getting_started_getting_help.md) +* [שאלות נפוצות](he-il/faq.md) + * [שאלות נפוצות כלליות](he-il/faq_general.md) +* [חומרה](he-il/hardware.md) +* התייחסויות + * [איך לתעד נכון](he-il/documentation_best_practices.md) + +**בשפה האנגלית** +* [המדריך המלא למתחילים](he-il/newbs.md) + * [התחלה](he-il/newbs_getting_started.md) + * [בנייה של הקושחה הראשונה שלך](he-il/newbs_building_firmware.md) + * [צריבה של הקושחה](he-il/newbs_flashing.md) + * [בדיקות ודיבאגינג](he-il/newbs_testing_debugging.md) + * [עבודה נכונה ב GIT](he-il/newbs_best_practices.md) + * [מקורות ללמידה](he-il/newbs_learn_more_resources.md) + +* [בסיס QMK](he-il/README.md) + * [מבוא לQMK](he-il/getting_started_introduction.md) + * [QMK CLI](he-il/cli.md) + * [QMK CLI Config](he-il/cli_configuration.md) + * [תרומה ל QMK](he-il/contributing.md) + * [איך להשתמש בGitHub](he-il/getting_started_github.md) + * [קבלת עזרה](he-il/getting_started_getting_help.md) + +* [שינויים משמעותיים](he-il/breaking_changes.md) + * [2019 Aug 30](he-il/ChangeLog/20190830.md) + +* [שאלות נפוצות](he-il/faq.md) + * [שאלות נפוצות כלליות](he-il/faq_general.md) + * [בנייה/קומפילציה של QMK](he-il/faq_build.md) + * [דיבאגינג ופתרון תקלות של QMK](he-il/faq_debug.md) + * [מיפוי מקשים](he-il/faq_keymap.md) + * [התקנת דרייברים עם Zadig](he-il/driver_installation_zadig.md) + +* מדריכים מפורטים + * [התקנת כלי Build](he-il/getting_started_build_tools.md) + * [מדריך Vagrant](he-il/getting_started_vagrant.md) + * [הוראות בנייה/קומפילציה](he-il/getting_started_make_guide.md) + * [צריבת קושחה](he-il/flashing.md) + * [התאמה אישית של הפונקציונאליות](he-il/custom_quantum_functions.md) + * [מיפוי מקשים](he-il/keymap.md) + +* [חומרה](he-il/hardware.md) + * [מעבדי AVR](he-il/hardware_avr.md) + * [דרייברים](he-il/hardware_drivers.md) + +* התייחסויות + * [מדריך למקלדות](he-il/hardware_keyboard_guidelines.md) + * [אפשרויות הגדרות](he-il/config_options.md) + * [קודי מקשים](he-il/keycodes.md) + * [קונבנציות קוד - C](he-il/coding_conventions_c.md) + * [קונבנציות קוד - Python](he-il/coding_conventions_python.md) + * [איך לתעד נכון](he-il/documentation_best_practices.md) + * [טמפלטים לדוקומנטציה](he-il/documentation_templates.md) + * [מילון](he-il/reference_glossary.md) + * [בדיקות יחידה](he-il/unit_testing.md) + * [פונקציות שימושיות](he-il/ref_functions.md) + * [תמיכה בConfigurator](he-il/reference_configurator_support.md) + * [פורמט info.json](he-il/reference_info_json.md) + * [פיתוח בPython CLI](he-il/cli_development.md) + +* [תכונות](he-il/features.md) + * [Basic Keycodes](he-il/keycodes_basic.md) + * [US ANSI Shifted Keys](he-il/keycodes_us_ansi_shifted.md) + * [Quantum Keycodes](he-il/quantum_keycodes.md) + * [Advanced Keycodes](he-il/feature_advanced_keycodes.md) + * [Audio](he-il/feature_audio.md) + * [Auto Shift](he-il/feature_auto_shift.md) + * [Backlight](he-il/feature_backlight.md) + * [Bluetooth](he-il/feature_bluetooth.md) + * [Bootmagic](he-il/feature_bootmagic.md) + * [Combos](he-il/feature_combo.md) + * [Command](he-il/feature_command.md) + * [Debounce API](he-il/feature_debounce_type.md) + * [DIP Switch](he-il/feature_dip_switch.md) + * [Dynamic Macros](he-il/feature_dynamic_macros.md) + * [Encoders](he-il/feature_encoders.md) + * [Grave Escape](he-il/feature_grave_esc.md) + * [Haptic Feedback](he-il/feature_haptic_feedback.md) + * [HD44780 LCD Controller](he-il/feature_hd44780.md) + * [Key Lock](he-il/feature_key_lock.md) + * [Layouts](he-il/feature_layouts.md) + * [Leader Key](he-il/feature_leader_key.md) + * [LED Matrix](he-il/feature_led_matrix.md) + * [Macros](he-il/feature_macros.md) + * [Mouse Keys](he-il/feature_mouse_keys.md) + * [OLED Driver](he-il/feature_oled_driver.md) + * [One Shot Keys](he-il/one_shot_keys.md) + * [Pointing Device](he-il/feature_pointing_device.md) + * [PS/2 Mouse](he-il/feature_ps2_mouse.md) + * [RGB Lighting](he-il/feature_rgblight.md) + * [RGB Matrix](he-il/feature_rgb_matrix.md) + * [Space Cadet](he-il/feature_space_cadet.md) + * [Split Keyboard](he-il/feature_split_keyboard.md) + * [Stenography](he-il/feature_stenography.md) + * [Swap Hands](he-il/feature_swap_hands.md) + * [Tap Dance](he-il/feature_tap_dance.md) + * [Terminal](he-il/feature_terminal.md) + * [Thermal Printer](he-il/feature_thermal_printer.md) + * [Unicode](he-il/feature_unicode.md) + * [Userspace](he-il/feature_userspace.md) + * [Velocikey](he-il/feature_velocikey.md) + +* למייקרים ומודרים + * [מדריך לכתיבה ידנית](he-il/hand_wire.md) + * [מדריך לצריבת ISP](he-il/isp_flashing_guide.md) + * [מדריך לדיבאגינג ARM](he-il/arm_debugging.md) + * [מנהל התקן I2C](he-il/i2c_driver.md) + * [מנהל התקן SPI](he-il/spi_driver.md) + * [בקרת GPIO](he-il/internals_gpio_control.md) + * [המרת Proton C](he-il/proton_c_conversion.md) + +* להבנה עמוקה יותר + * [איך עובדות מקלדות](he-il/how_keyboards_work.md) + * [להבין את QMK](he-il/understanding_qmk.md) + +* נושאים נוספים + * [שימוש ב - Eclipse עם QMK](he-il/other_eclipse.md) + * [שימוש ב - VSCode עם QMK](he-il/other_vscode.md) + * [תמיכה](he-il/getting_started_getting_help.md) + * [כיצד להוסיף תרגום](he-il/translating.md) + +* QMK מבפנים (בתהליך) + * [Defines](he-il/internals_defines.md) + * [Input Callback Reg](he-il/internals_input_callback_reg.md) + * [Midi Device](he-il/internals_midi_device.md) + * [Midi Device Setup Process](he-il/internals_midi_device_setup_process.md) + * [Midi Util](he-il/internals_midi_util.md) + * [Send Functions](he-il/internals_send_functions.md) + * [Sysex Tools](he-il/internals_sysex_tools.md) + +
diff --git a/he-il/documentation_best_practices.md b/he-il/documentation_best_practices.md new file mode 100644 index 00000000000..90c4a137a04 --- /dev/null +++ b/he-il/documentation_best_practices.md @@ -0,0 +1,67 @@ +
+# איך לתעד נכון + +עמוד זה קיים כדי לתעד את השיטות הטובות ביותר כאשר כותבים תיעוד עבור QMK. מעקב אחר הוראות אלה יעזור לשמור על סגנון וטון עקביים, אשר בתורם יעזרו לאנשים אחרים להבין טוב יותר את QMK. + +# פתיחת עמוד + +התיעוד שלך צריך בד״כ להפתח עם כותרת בגודל H1, אחריה פסקה אחת של תיאור של מה המשתמש ימצא בעמוד זה. +זכור כי כותרת זו והפסקה ימוקמו ליד תוכן העניינים, אז חשוב לשמור על כותרת קצרה ולהמנע ממשפטים ארוכים ללא פיסוק. + +לדוגמה: + +``` +# הכותרת שלי + +עמוד זה מדבר על היכולת הסופר-מגניבה שלי. אתה יכול להשתמש ביכולת זו כדי להכין קפה, לסחוט תפוזים ולקבל משלוח של ביצים ועוגות מהסופר הקרוב באמצעות רחפן. +``` + +# כותרות + +עמוד התיעוד צריך לאופן כללי לכלול מס׳ כותרות בגודל "H1". רק כותרות מגודל H1 ו- H2 יכללו בתוכן העניינים, אז חשוב לתכנן אותם בהתאם. הכותרות לא להיות רחבות מידי כדי למנוע מתוכן העניינים להפוך להיות רחב מידי + +# בלוקי רמיזה מעוצבים + +ניתן להוסיף בלוקי רמיזה מעוצבים שמצויירים מסביב לטקסט כדי למשוך תשומת לב אליו. + +### חשוב + +``` +!> זה חשוב +``` + +יתרנדר כ: + +!> זה חשוב + +### טיפים כלליים + +``` +?> זהו טיפ שימושי. +``` + +יתרנדר כ: + +?> זהו טיפ שימושי. + + +# תיעוד יכולות ופיצ׳ריםDocumenting Features + +אם יוצרים יכולת חדשה ב QMK, צרו עמוד תיעוד עבורה. העמוד לא צריך להיות ארוך במיוחד, מספר משפטים המתארים את היכולת (פיצ׳ר) וטבלה המתארת קודי מקשים רלוונטיים זה מספיק. הנה דוגמה בסיסית: + +```markdown +# הפיצ׳ר המגניב שלי + +עמוד זה מדבר על היכולת הסופר-מגניבה שלי. אתה יכול להשתמש ביכולת זו כדי להכין קפה, לסחוט תפוזים ולקבל משלוח של ביצים ועוגות מהסופר הקרוב באמצעות רחפן. + +## קודי המקשים המגניבים של היכולת שלי + +|Long Name|Short Name|Description| +|---------|----------|-----------| +|KC_COFFEE||Make Coffee| +|KC_CREAM||Order Cream| +|KC_SUGAR||Order Sugar| +``` + +מקמו את התיעוד שלכם בתוך `docs/feature_.md`, והוסיפו קישור לקובץ זה במקום המתאים ב `docs/_sidebar.md`. אם הוספתם קודי מקשים נוספים, תקפידו להוסיף אותם ל- `docs/keycodes.md` עם לינק לעמוד היכולת שלכם. +
\ No newline at end of file diff --git a/he-il/faq.md b/he-il/faq.md new file mode 100644 index 00000000000..88ea07fbe71 --- /dev/null +++ b/he-il/faq.md @@ -0,0 +1,8 @@ +
+# שאלות נפוצות + +* [כללי](faq_general.md) +* [בנייה או קומפילציה של QMK](faq_build.md) +* [דיבאגינג ופתרון בעיות של QMK](faq_debug.md) +* [מיפוי מקשים](faq_keymap.md) +
\ No newline at end of file diff --git a/he-il/faq_general.md b/he-il/faq_general.md new file mode 100644 index 00000000000..26286d552f0 --- /dev/null +++ b/he-il/faq_general.md @@ -0,0 +1,17 @@ +
+# שאלות נפוצות + +## מה זה QMK? + +[QMK](https://github.com/qmk), קיצור עבור Quantum Mechanical Keyboard, הוא קבוצה של אנשים הבונים כלים עבור מקלדות מותאמות אישית. התחלנו עם [קושחת QMK](https://github.com/qmk/qmk_firmware), פורק של [TMK](https://github.com/tmk/tmk_keyboard) אשר שונה באופן ניכר. + +## מה ההבדלים העיקריים בין QMK ו-Keymap TMK? + +TMK עוצב ומומש במקור ע״י [Jun Wako](https://github.com/tmk). QMK התחיל כפורק של [Jack Humbert](https://github.com/jackhumbert) של הפרוייקט של TMK עבור Planck. אחרי כמה זמן הפורק של ג׳ק השתנה מזה של TMK וב- 2015 ג׳ק החליט לשנות את שמו של הפורק ל- QMK. + +מנק׳ מבט טכנית, QMK נבנה על גבי TMK ע״י הוספת יכולות ופיצ׳רים חדשים. ראוי לציון ש- QMK הרחיב את מס׳ קודי המקלדת האפשריים ומשתמש בהם למימוש יכולות מתקדמות כמו `S()`, `LCTL()`, ו- `MO()`. ניתן לראות רשימה מלאה של קודי המקלדת האלה ב - [קודי מקלדת](keycodes.md). + +מנק׳ מבט של הפרוייקט וניהול הקהילה, TMK מנהל את כל המקלדות הנתמכות בעצמו, עם מעט תמיכה מהקהילה. כל אחד יכול לעשות פורק מהפרוייקט עבור מקלדות אחרות. רק מס׳ מיפויי מקשים נמצאים בברירת המחדל כך שאנשים בד״כ לא משתפים מיפויי מקשים זה עם זה. QMK מעודד את השיתוף של המקלדות וקודי המקשים דרך רפוזיטורי בניהול מרכזי, אשר מקבל את כל בקשות ה- Pull Requests שעומדות בסטנדרט האיכות. רובם מנוהלות ע״י הקהילה, אבל הצוות של QMK עוזר כשנדרש. + +לשתי הגישות יש יתרונות וחסרונות וקוד עובר בחופשיות בין TMK ל- QMK כשצריך. +
\ No newline at end of file diff --git a/he-il/getting_started_getting_help.md b/he-il/getting_started_getting_help.md new file mode 100644 index 00000000000..e62c9f403dd --- /dev/null +++ b/he-il/getting_started_getting_help.md @@ -0,0 +1,17 @@ +
+# קבלת עזרה + +ישנם משאבים רבים לצורך קבלת עזרה עם QMK. + +## צ׳אט בזמן אמת + +אפשר למצוא מפתחי QMK ומשתמשים [בשרת ה-Discord הראשי שלנו](https://discord.gg/Uq7gcHh). ישנם ערוצים ספציפיים בשרת לצורך שיחות על הקושחה, ארגז הכלים, חומרה והמגדיר. + +## סאב-רדיט OLKB + +הפורום הרשמי של QMK נמצא ב - [/r/olkb](https://reddit.com/r/olkb) באתר [reddit.com](https://reddit.com). + +## סוגיות GitHub + +ניתן לפתוח [סוגייה ב-GitHub](https://github.com/qmk/qmk_firmware/issues). הדבר שימושי במיוחד כאשר הסוגיה דורשת דיון עמוק וארוך או דיבאגינג. +
\ No newline at end of file diff --git a/he-il/getting_started_github.md b/he-il/getting_started_github.md new file mode 100644 index 00000000000..5cafac5ac56 --- /dev/null +++ b/he-il/getting_started_github.md @@ -0,0 +1,75 @@ +
+# איך להשתמש ב-GitHub עם QMK + +GitHub עלול להיות קצת טריקי למי שלא מכיר את העבודה איתו - מדריך זה ילווה אתכם שלב אחר שלב דרך ביצוע פעולות fork, clone ו-pull request עם QMK. + +?> מדריך זה מניח שאתם מרגישים בנוח עם הרצה של פקודות בסביבת command line (שורת הפקודה) ו-git מותקן במערכת שלכם. + +התחילו ב- [עמוד של QMK ב-GitHub](https://github.com/qmk/qmk_firmware), ותצמאו כפתור בחלק העליון מימין עם התיכוב "Fork": + +![Fork ב-GitHub](http://i.imgur.com/8Toomz4.jpg) + +אם אתם חלק מארגון, תצטרכו לבחור לאיזה חשבון לבצע פעולת fork. ברוב המבקרים, תרצו לבצע fork לתוך החשבון הפרטי שלכם. ברגע שה-fork הסתיים (לפעמים זה יכול לקחת קצת זמן) הקליקו על כפתור ה-"Clone or Download": + +![הורדה מ-GitHub](http://i.imgur.com/N1NYcSz.jpg) + +תוודאו שאתם בוחרים באופצייה של "HTTPS", בחרו את הקישור והעתיקו אותו: + +![קישור HTTPS](http://i.imgur.com/eGO0ohO.jpg) + +מכאן והלאה, הקיש `git clone --recurse-submodules ` בשורת הפקודה והדביקו את הלינק שלכם: + +
+ +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +
+ +כעת, יש לכם את ה-fork של QMK על המכונה המקומית שלכם ואתם יכולים להוסיף את מיפויי המקשים שלכם, לקמפל את הפרוייקט ולצרוב אותו על הלוח שלכם. כשאתם שלמים עם השינוי שעשיתם, תוכלו להוסיף, לבצע פעולת commit ולדחוף את השינויים ל-fork שלכם באופן הבא: + +
+ +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +
+ +השינויים שלכם יופיעו ב-fork שלכם ב-GitHub - אם תחזרו לשם (`https://github.com//qmk_firmware`), תוכלו ליצור "Pull Request חדש" ע״י הקשה על הכפתור הבא: + +![Pull Request חדש](http://i.imgur.com/DxMHpJ8.jpg) + +כאן תוכלו לראות בדיוק למה עשיתם commit - אם הכל נראה תקין, תוכלו להשלים את הפעולה ע״י הקשה על "Create Pull Request": + +![צרו Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +אחרי שהגשתם, אנו עלולים לפנות אליכם לגבי השינויים שהצעתם, נבקש שתבצעו שינויים ובסופו של דבר נקבל את השינויים! תודה שתרמתם לפרוייקט QMK :) +
diff --git a/he-il/getting_started_introduction.md b/he-il/getting_started_introduction.md new file mode 100644 index 00000000000..fca86bdaaf4 --- /dev/null +++ b/he-il/getting_started_introduction.md @@ -0,0 +1,72 @@ +
+# מבוא + +עמוד זה מנסה להסביר את המידע הבסיסי אותו תדרשו לדעת כדי לעבוד עם פרוייקט QMK. הוא מניח שאתם יודעים איך לנווט בסביבת Unix Shell, אבל לא מניח שאתם מכירים את שפת C או קומפילציה באמצעות make. + +## מבנה QMK בסיסי + +QMK הוא פורק של הפרוייקט [tmk_keyboard](https://github.com/tmk/tmk_keyboard) של [Jun Wako](https://github.com/tmk). קוד הTMK המקורי, עם התאמות, יכול להמצא בתיקיית `tmk_core`. התוספות של QMK לפרוייקט יכולות להמצא בתיקיית `quantum`. פרוייקטי מקלדות יכולות להמצא בתיקיות `handwired` ו- `keyboard`. + +### מבנה אחסון המשתמש + +בתוך תיקיית `users` יש תיקייה לכל משתמש. זה המקום למשתמשים להוסיף קוד שהם רוצים להשתמש בו במקלדות שונות. מומלץ לעיין במסמך [תכונות אחסון המשתמש](feature_userspace.md) לקבלת מידע נוסף. + +### מבנה פרוייקט המקלדת + +בתוך תיקיית `keyboards`, תת התיקייה `handwired` ותת התיקיות של היצרן והמוכר, לדוגמה `clueboard` היא תיקייה לכל פרוייקט מקלדת - `qmk_firmware/keyboards/clueboard/2x1800` בתוך התיקייה הזאת תמצאו את המבנה הבא: + + +* `keymaps/`: מיפויי מקשים שונים היכולים להבנות +* `rules.mk`: קובץ המגדיר את הגדרות ברירת המחדל של `make`. נא לא לערוך את הקובץ ישירות, במקום זאת, השתמשו בקובץ מיפוי המקשים ספציפי `rules.mk`. +* `config.h`: הקובץ מכיל הגדרות לזמן הקומפילציה. נא לא לערוך את הקובץ ישירות אלא להשתמש בקובץ `config.h` לכל מיפויי מקשים. +* `info.json`: הקובץ מכיל הגדרות פריסה עבור QMK Configurator. צפו ב [תמיכת Configurator](reference_configurator_support.md) למידע נוסף. +* `readme.md`: סקירה כללית של המקלדת. +* `.h`: הקובץ בו פריסת המקלדת מוגדרת אל מול מטריצת המתגים של המקלדת. +* `.c`: הקובץ בו ניתן למצוא קוד מותאם למקלדת. + +למידע נוסף - אנא הכנסו ל [QMK](hardware_keyboard_guidelines.md). +For more information on project structure, see [QMK מדריך למקלדת](hardware_keyboard_guidelines.md). + +### מבנה מפיוי המקשים + +בכל ספריית מיפוי מקשים, הקבצים הבאים עלולים להמצא. רק הקובץ `keymap.c` הוא חובה, אם השאר לא נמצאים, אפשרויות ברירת המחדל יבחרו. +In every keymap folder, the following files may be found. Only `keymap.c` is required, and if the rest of the files are not found the default options will be chosen. + +* `config.h`: ההגדרות השונות עבור מיפוי המקשים. +* `keymap.c`: כל הקודים של מיפוי המקשים, קובץ חובה +* `rules.mk`: אילו יכולות של QMK מאופשרות. +* `readme.md`: הסבר על מיפוי המקשים, איך אחרים ישתמשו בו והסבר על היכולות. נא להעלות תמונות לשירותים כמו imgur. + +# קובץ `config.h` + +לקובץ `config.h` יש 3 מיקומים אפשריים: + +* keyboard (`/keyboards//config.h`) +* userspace (`/users//config.h`) +* keymap (`/keyboards//keymaps//config.h`) + +מערכת הבילד אוטומטית בוחרת את קובץ ההגדרות לפי הסדר הנ״ל. אם רוצים לדרוס הגדרה מסויימת שהוגדרה בקובץ `config.h` קודם, ראשית תצטרכו להשתמש בקוד מוכן עבור ההגדרות שאתם רוצים לשנות. + +
+ +``` +#pragma once +``` + +
+ +כדי לדרוס הגדרות מקובץ `config.h` קודם, אתם מוכרחים להשתמש בפקודת `#undef` ואז שוב `#define`. + +דוגמה לקוד כזה נראית כך: +
+ +``` +#pragma once + +// overrides go here! +#undef MY_SETTING +#define MY_SETTING 4 +``` + +
+
diff --git a/he-il/hardware.md b/he-il/hardware.md new file mode 100644 index 00000000000..441792e031b --- /dev/null +++ b/he-il/hardware.md @@ -0,0 +1,10 @@ +
+# חומרה + +QMK רצה על מגוון של חומרות. אם המעבד שלך יכול להיות ממוקד (מטורגט) ע״י [LUFA](http://www.fourwalledcubicle.com/LUFA.php) או [ChibiOS](http://www.chibios.com) כנראה שתוכל לגרום ל QMK לרוץ על המעבד. קטע זה מדבר על הרצת QMK, ותקשורת עם, סוגים שונים של חומרות. + +* [מדריך למקלדת](hardware_keyboard_guidelines.md) +* [מעבדי AVR](hardware_avr.md) +* מעבדי ARM (TBD) +* [מנהלי התקנים](hardware_drivers.md) +
\ No newline at end of file diff --git a/he-il/newbs_learn_more_resources.md b/he-il/newbs_learn_more_resources.md new file mode 100644 index 00000000000..8792a9de0a7 --- /dev/null +++ b/he-il/newbs_learn_more_resources.md @@ -0,0 +1,16 @@ +
+# מקורות ללמידה + +המקורות הבאים מטרתם היא לתת למשתמשים חדשים בקהילת QMK כדי להבין לעומק את המידע שמגיע במסמכי המתחילים. + +מקורות גיט: + +* [מדריך כללי מעולה](https://www.codecademy.com/learn/learn-git) +* [משחק גיט כדי ללמוד מדוגמאות](https://learngitbranching.js.org/) +* [מקורות גיט כדי ללמוד עוד על GitHub](getting_started_github.md) +* [מקור גיט כדי ללמוד במפורש על QMK](contributing.md) + +מקורות לפקודות שורה (Command Line): + +* [מדריך טוב על Command Line](https://www.codecademy.com/learn/learn-the-command-line) +
\ No newline at end of file diff --git a/he-il/proton_c_conversion.md b/he-il/proton_c_conversion.md new file mode 100644 index 00000000000..9642ca30905 --- /dev/null +++ b/he-il/proton_c_conversion.md @@ -0,0 +1,36 @@ +
+# המרה של לוח להשתמש ב-Proton C + +אם לוח נתמך ב-QMK משתמש בלוח Pro Micro (או כל לוח נתמך) ואתם רוצים להשתמש ב-Proton C, ניתן לייצר את החומרה ע"י הוספה של הפקודה `CONVERT_TO_PROTON_C=yes` (או `CTPC=yes`) לפקודת make, כמו כאן: +
+ +``` + make 40percentclub/mf68:default CTPC=yes +``` + +
+ניתן להוסיף את אותו ארגומנט לקובץ `rules.mk` במיפוי המקשים שלכם, שתיצור את אותה התוצאה. + +הדבר חושף את דגל `CONVERT_TO_PROTON_C` שניתן להשתמש בו בקוד שלכם באמצעות פקודת `#ifdef`, כמו כאן: +
+ +``` + #ifdef CONVERT_TO_PROTON_C + // Proton C code + #else + // Pro Micro code + #endif +``` + +
+לפני שתצליחו לקמפל, יכול להיות שתקבלו שגיאות שונות לגבי `PORTB/DDRB`, וכו' שלא הוגדרו, אם כך, תצטרכו להמיר את קודי המקלדת להשתמש ב - [בקרי GPIO](internals_gpio_control.md) שיעבדו עבור ARM וגם AVR. הדבר לא אמור להשפיע על הבילדים של AVR בכלל. + +ל-Proton C יש רק מנורת LED אחת על הלוח (C13), וכברירת מחדל, TXLED (D5) ממופה אליו. אם תרצו במקום, למפות אליו את RXLED (B0), הוסיפו את השורה הבא לקובץ `config.h`: +
+ +``` + #define CONVERT_TO_PROTON_C_RXLED +``` + +
+
diff --git a/he-il/quantum_keycodes.md b/he-il/quantum_keycodes.md new file mode 100644 index 00000000000..5374fd47ad4 --- /dev/null +++ b/he-il/quantum_keycodes.md @@ -0,0 +1,25 @@ +
+# קודי מקלדת Quantum + +קודי מקלדת Quantum מאפשרים התאמה נוחה יותר של מיפוי המקשים שלך מעבר למה שהבסיסי מאפשר, ללא צורך בהגדרת של פעולות מותאמות אישית. + +כל קודי המקלדת בתוך quantum הם מספרים בין `0x0000` ֿֿֿ ל-`0xFFFF`. בתוך הקובץ `keymap.c` זה עלול להראות כאילו יש לך פונקציות ומקרים יחודיים נוספים, אבל בסופו של דבר הקדם-מעבד של שפת C יתרגם אלה לתוך מספר יחיד בין 4 בתים. QMK שמרה את מרחב הכתובות בין `0x0000` עד ל- `0x00FF` עבור קודי מקשים סטנדרטיים. קודי מקשים אלה, כגון `KC_A`, `KC_1`, ו- `KC_LCTL`, אשר מתארים מקשים בסיסיים מוגדרים בתוך USB HID specification. + +בעמודו זה יש לנו את קודי המקשים מתועדים בין `0x00FF` ֿֿ ל- `0xFFFF` אשר משומשים בשביל לממש יכולות מתקדמות של quantum. אם תגדירו קודי מקשים משלכם, הם יתווספו לתוך המרחב הזה גם כן. + +## קודי מקשים של QMK +
+ +``` +|Key |Aliases |Description | +|---------------|-----------|---------------------------------------------------------------------| +|`RESET` | |Put the keyboard into DFU mode for flashing | +|`DEBUG` | |Toggle debug mode | +|`EEPROM_RESET` |`EEP_RST` |Resets EEPROM state by reinitializing it | +|`KC_GESC` |`GRAVE_ESC`|Escape when tapped, ` when pressed with Shift or GUI| +|`KC_LEAD` | |The [Leader key](feature_leader_key.md) | +|`KC_LOCK` | |The [Lock key](feature_key_lock.md) | +``` + +
+
diff --git a/how_a_matrix_works.md b/how_a_matrix_works.md new file mode 100644 index 00000000000..df7d164cbbb --- /dev/null +++ b/how_a_matrix_works.md @@ -0,0 +1,99 @@ +# How a Keyboard Matrix Works + +Keyboard switch matrices are arranged in rows and columns. Without a matrix circuit, each switch would require its own wire directly to the controller. + +When the circuit is arranged in rows and columns, if a key is pressed, a column wire makes contact with a row wire and completes a circuit. The keyboard controller detects this closed circuit and registers it as a key press. + +The microcontroller will be set up via the firmware to send a logical 1 to the columns, one at a time, and read from the rows, all at once - this process is called matrix scanning. The matrix is a bunch of open switches that, by default, don't allow any current to pass through - the firmware will read this as no keys being pressed. As soon as you press one key down, the logical 1 that was coming from the column the keyswitch is attached to gets passed through the switch and to the corresponding row - check out the following 2x2 example: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + row0 ---(key0)---(key1) row0 ---(key0)---(key1) + | | | | + row1 ---(key2)---(key3) row1 ---(key2)---(key3) + +The `x` represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an `x`. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column. + +When we press `key0`, `col0` gets connected to `row0`, so the values that the firmware receives for that row is `0b01` (the `0b` here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1) + | | | | + row1 ---(key2)---(key3) row1 ---(key2)---(key3) + +We can now see that `row0` has an `x`, so has the value of 1. As a whole, the data the firmware receives when `key0` is pressed is: + + col0: 0b01 + col1: 0b00 + │└row0 + └row1 + +A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1) + | | | | + x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3) + + Remember that this ^ is still connected to row1 + +The data we get from that is: + + col0: 0b11 + col1: 0b11 + │└row0 + └row1 + +Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this; + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + │ │ | │ + (key0) (key1) (key0) (key1) + ! │ ! │ ! | ! │ + row0 ─────┴────────┘ │ row0 ─────┴────────┘ │ + │ │ | │ + (key2) (key3) (key2) (key3) + ! ! ! ! + row1 ─────┴────────┘ row1 ─────┴────────┘ + +In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|` + +Now when we press the three keys, invoking what would be a ghosting scenario: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + │ │ │ │ + (┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1) + ! │ ! │ ! │ ! │ + x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │ + │ │ │ │ + (key2) (┌─┘3) (key2) (┌─┘3) + ! ! ! ! + row1 ─────┴────────┘ x row1 ─────┴────────┘ + +Things act as they should! Which will get us the following data: + + col0: 0b01 + col1: 0b11 + │└row0 + └row1 + +The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS. + +Further reading: +- [Wikipedia article](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit) +- [Deskthority article](https://deskthority.net/wiki/Keyboard_matrix) +- [Keyboard Matrix Help by Dave Dribin (2000)](https://www.dribin.org/dave/keyboard/one_html/) +- [How Key Matrices Works by PCBheaven](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (animated examples) +- [How keyboards work - QMK documentation](how_keyboards_work.md) diff --git a/how_keyboards_work.md b/how_keyboards_work.md new file mode 100644 index 00000000000..3dcbc645222 --- /dev/null +++ b/how_keyboards_work.md @@ -0,0 +1,76 @@ +# How Keys Are Registered, and Interpreted by Computers + +In this file, you can will learn the concepts of how keyboards work over USB, +and you'll be able to better understand what you can expect from changing your +firmware directly. + +## Schematic View + +Whenever you type on 1 particular key, here is the chain of actions taking +place: + +``` text ++------+ +-----+ +----------+ +----------+ +----+ +| User |-------->| Key |------>| Firmware |----->| USB wire |---->| OS | ++------+ +-----+ +----------+ +----------+ +----+ +``` + +This scheme is a very simple view of what's going on, and more details follow +in the next sections. + +## 1. You Press a Key + +Whenever you press a key, the firmware of your keyboard can register this event. +It can register when the key is pressed, held and released. + +This usually happens with a periodic scan of key presses. This speed often is limited by the mechanical key response time, the protocol to transfer those key presses (here USB HID), and by the software it is used in. + +## 2. What the Firmware Sends + +The [HID specification](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) tells what a keyboard can actually send through USB to have a chance to be properly recognised. This includes a pre-defined list of scancodes which are simple numbers from `0x00` to `0xE7`. The firmware assigns a scancode to each key of the keyboard. + +The firmware does not send actual letters or characters, but only scancodes. +Thus, by modifying the firmware, you can only modify what scancode is sent over +USB for a given key. + +## 3. What the Event Input/Kernel Does + +The *scancode* is mapped to a *keycode* dependent on the keyboard [60-keyboard.hwdb at Master](https://github.com/systemd/systemd/blob/master/hwdb.d/60-keyboard.hwdb). Without this mapping, the operating system will not receive a valid keycode and will be unable to do anything useful with that key press. + +## 4. What the Operating System Does + +Once the keycode reaches the operating system, a piece of software has to have +it match an actual character thanks to a keyboard layout. For example, if your +layout is set to QWERTY, a sample of the matching table is as follows: + +| keycode | character | +|---------|-----------| +| 0x04 | a/A | +| 0x05 | b/B | +| 0x06 | c/C | +| ... | ... | +| 0x1C | y/Y | +| 0x1D | z/Z | +| ... | ... | + +## Back to the Firmware + +As the layout is generally fixed (unless you create your own), the firmware can actually call a keycode by its layout name directly to ease things for you. This is exactly what is done here with `KC_A` actually representing `0x04` in QWERTY. The full list can be found in [keycodes](keycodes.md). + +## List of Characters You Can Send + +Putting aside shortcuts, having a limited set of keycodes mapped to a limited layout means that **the list of characters you can assign to a given key are only the ones present in the layout**. + +For example, this means that if you have a QWERTY US layout, and you want to assign one key to produce `€` (euro currency symbol), you are unable to do so, because the QWERTY US layout does not have such mapping. You could fix that by using a QWERTY UK layout, or a QWERTY US International. + +You may wonder why a keyboard layout containing all of Unicode is not devised then? The limited number of keycodes available through USB simply disallows such a thing. + +## How to (Maybe) Enter Unicode Characters + +You can have the firmware send *sequences of keys* to use the [software Unicode Input Method](https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_input) of the target operating system, thus effectively entering characters independently of the layout defined in the OS. + +Yet, it does come with multiple disadvantages: + + - Tied to a specific OS at a time (need recompilation when changing OS); + - Within a given OS, does not work in all software; + - Limited to a subset of Unicode on some systems. diff --git a/i2c_driver.md b/i2c_driver.md new file mode 100644 index 00000000000..0103e1b4ccc --- /dev/null +++ b/i2c_driver.md @@ -0,0 +1,133 @@ +# I2C Master Driver :id=i2c-master-driver + +The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs. + +## An important note on I2C Addresses :id=note-on-i2c-addresses + +All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting +the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed +on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be +shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`. + +You can either do this on each call to the functions below, or once in your definition of the address. For example if your device has an address of `0x18`: + +`#define MY_I2C_ADDRESS (0x18 << 1)` + +See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details. + +## Available functions :id=available-functions + +|Function |Description | +|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`void i2c_init(void);` |Initializes the I2C driver. This function should be called once before any transaction is initiated. | +|`i2c_status_t i2c_start(uint8_t address, uint16_t timeout);` |Starts an I2C transaction. Address is the 7-bit slave address without the direction bit. | +|`i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` |Transmit data over I2C. Address is the 7-bit slave address without the direction. Returns status of transaction. | +|`i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` |Receive data over I2C. Address is the 7-bit slave address without the direction. Saves number of bytes specified by `length` in `data` array. Returns status of transaction. | +|`i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_transmit` function but `regaddr` sets where in the slave the data will be written. | +|`i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read. | +|`i2c_status_t i2c_stop(void);` |Ends an I2C transaction. | + +### Function Return :id=function-return + +All the above functions, except `void i2c_init(void);` return the following truth table: + +|Return Constant |Value|Description | +|--------------------|-----|--------------------------------| +|`I2C_STATUS_SUCCESS`|0 |Operation executed successfully.| +|`I2C_STATUS_ERROR` |-1 |Operation failed. | +|`I2C_STATUS_TIMEOUT`|-2 |Operation timed out. | + + +## AVR :id=avr + +### Configuration :id=avr-configuration + +The following defines can be used to configure the I2C master driver. + +|Variable |Description |Default| +|------------------|---------------------------------------------------|-------| +|`F_SCL` |Clock frequency in Hz |400KHz | + +AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required. + +## ARM :id=arm + +For ARM the Chibios I2C HAL driver is under the hood. +This section assumes an STM32 MCU. + +### Configuration :id=arm-configuration + +The configuration for ARM MCUs can be quite complex as often there are multiple I2C drivers which can be assigned to a variety of ports. + +Firstly the `mcuconf.h` file must be setup to enable the necessary hardware drivers. + +|Variable |Description |Default| +|------------------------------|------------------------------------------------------------------------------------|-------| +|`#STM32_I2C_USE_XXX` |Enable/Disable the hardware driver XXX (each driver should be explicitly listed) |FALSE | +|`#STM32_I2C_BUSY_TIMEOUT` |Time in ms until the I2C command is aborted if no response is received |50 | +|`#STM32_I2C_XXX_IRQ_PRIORITY` |Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING) |10 | +|`#STM32_I2C_USE_DMA` |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit |TRUE | +|`#STM32_I2C_XXX_DMA_PRIORITY` |Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING) |1 | + +Secondly, in the `halconf.h` file, `#define HAL_USE_I2C` must be set to `TRUE`. This allows ChibiOS to load its I2C driver. + +Lastly, we need to assign the correct GPIO pins depending on the I2C hardware driver we want to use. + +By default the I2C1 hardware driver is assumed to be used. If another hardware driver is used, `#define I2C_DRIVER I2CDX` should be added to the `config.h` file with X being the number of hardware driver used. For example is I2C3 is enabled, the `config.h` file should contain `#define I2C_DRIVER I2CD3`. This aligns the QMK I2C driver with the Chibios I2C driver. + +STM32 MCUs allows a variety of pins to be configured as I2C pins depending on the hardware driver used. By default B6 and B7 are set to I2C. You can use these defines to set your i2c pins: + +| Variable | Description | Default | +|--------------------------|----------------------------------------------------------------------------------------------|---------| +| `I2C1_SCL_BANK` | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`) to use for SCL | `GPIOB` | +| `I2C1_SDA_BANK` | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`) to use for SDA | `GPIOB` | +| `I2C1_SCL` | The pin number for the SCL pin (0-15) | `6` | +| `I2C1_SDA` | The pin number for the SDA pin (0-15) | `7` | +| `I2C1_BANK` (deprecated) | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`), superceded by `I2C1_SCL_BANK`, `I2C1_SDA_BANK` | `GPIOB` | + +The ChibiOS I2C driver configuration depends on STM32 MCU: + + STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1; + STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2; + +#### I2Cv1 :id=i2cv1 +STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using as a reference: + +| Variable | Default | +|--------------------|------------------| +| `I2C1_OPMODE` | `OPMODE_I2C` | +| `I2C1_CLOCK_SPEED` | `100000` | +| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` | + +#### I2Cv2 :id=i2cv2 +STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using as a reference: + +| Variable | Default | +|-----------------------|---------| +| `I2C1_TIMINGR_PRESC` | `15U` | +| `I2C1_TIMINGR_SCLDEL` | `4U` | +| `I2C1_TIMINGR_SDADEL` | `2U` | +| `I2C1_TIMINGR_SCLH` | `15U` | +| `I2C1_TIMINGR_SCLL` | `21U` | + +STM32 MCUs allow for different "alternate function" modes when configuring GPIO pins. These are required to switch the pins used to I2Cv2 mode. See the respective datasheet for the appropriate values for your MCU. + +| Variable | Default | +|---------------------|---------| +| `I2C1_SCL_PAL_MODE` | `4` | +| `I2C1_SDA_PAL_MODE` | `4` | + +#### Other :id=other +You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function: + +```c +void i2c_init(void) +{ + setPinInput(B6); // Try releasing special pins for a short time + setPinInput(B7); + wait_ms(10); // Wait for the release to happen + + palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function + palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function +} +``` diff --git a/index.html b/index.html new file mode 100644 index 00000000000..5cab97a57fa --- /dev/null +++ b/index.html @@ -0,0 +1,166 @@ + + + + + QMK Firmware + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + diff --git a/internals_SERIAL_USB.md b/internals_SERIAL_USB.md new file mode 100644 index 00000000000..c7fe2662841 --- /dev/null +++ b/internals_SERIAL_USB.md @@ -0,0 +1,314 @@ +# group `SERIAL_USB` {#group___s_e_r_i_a_l___u_s_b} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`_qmk_usb_driver_data`](#group___s_e_r_i_a_l___u_s_b_1ga623f2c1e20bb296cf3cbdc88d153b6c9) | `SerialDriver` specific data. +`define `[`_qmk_usb_driver_methods`](#group___s_e_r_i_a_l___u_s_b_1ga798bce936d06cb5332a1c0e545b84dbb) | `SerialUSBDriver` specific methods. +`enum `[`qmkusbstate_t`](#group___s_e_r_i_a_l___u_s_b_1ga534e1c5933a7c4785f5882ad21674302) | Driver state machine possible states. +`public static bool `[`qmkusb_start_receive`](#group___s_e_r_i_a_l___u_s_b_1ga4a2db2450b14c2a07c681b5d9429d76e)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | +`public static size_t `[`_write`](#group___s_e_r_i_a_l___u_s_b_1ga5e8117f4f91892c3d46076b0853b9116)`(void * ip,const uint8_t * bp,size_t n)` | +`public static size_t `[`_read`](#group___s_e_r_i_a_l___u_s_b_1gac07ed241c806363b6d298d7b4e2c3dad)`(void * ip,uint8_t * bp,size_t n)` | +`public static msg_t `[`_put`](#group___s_e_r_i_a_l___u_s_b_1ga240a53ff8cbb972b8e9ccdd4cdbcaedd)`(void * ip,uint8_t b)` | +`public static msg_t `[`_get`](#group___s_e_r_i_a_l___u_s_b_1ga0ef118239efc83deca980513e7330658)`(void * ip)` | +`public static msg_t `[`_putt`](#group___s_e_r_i_a_l___u_s_b_1ga63abfd1c739742e5ae219f15824e47ca)`(void * ip,uint8_t b,sysinterval_t timeout)` | +`public static msg_t `[`_gett`](#group___s_e_r_i_a_l___u_s_b_1ga122f8c98aa183cf27022ea53a7cac4d5)`(void * ip,sysinterval_t timeout)` | +`public static size_t `[`_writet`](#group___s_e_r_i_a_l___u_s_b_1ga015a4300ed5207dec4541348a9a04671)`(void * ip,const uint8_t * bp,size_t n,sysinterval_t timeout)` | +`public static size_t `[`_readt`](#group___s_e_r_i_a_l___u_s_b_1ga87af5dde7865331b7634b63a3b004914)`(void * ip,uint8_t * bp,size_t n,sysinterval_t timeout)` | +`public static void `[`ibnotify`](#group___s_e_r_i_a_l___u_s_b_1ga278a0b24aa52959889f37ab7e8041698)`(io_buffers_queue_t * bqp)` | Notification of empty buffer released into the input buffers queue. +`public static void `[`obnotify`](#group___s_e_r_i_a_l___u_s_b_1gaf0e8ad9d01f2cbe14aa5a4e49f099547)`(io_buffers_queue_t * bqp)` | Notification of filled buffer inserted into the output buffers queue. +`public void `[`qmkusbInit`](#group___s_e_r_i_a_l___u_s_b_1ga3853659326b42a6df413177ff65d7c15)`(void)` | Serial Driver initialization. +`public void `[`qmkusbObjectInit`](#group___s_e_r_i_a_l___u_s_b_1gaf8ba926d88993cb4fab100f1ef427e0b)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp,const `[`QMKUSBConfig`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_config)` * config)` | Initializes a generic full duplex driver object. +`public void `[`qmkusbStart`](#group___s_e_r_i_a_l___u_s_b_1ga82f3c032f7fb6832a60d6048f69c3e3d)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp,const `[`QMKUSBConfig`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_config)` * config)` | Configures and starts the driver. +`public void `[`qmkusbStop`](#group___s_e_r_i_a_l___u_s_b_1gaa032aca2a467800dc0dc0e205b4757d5)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | Stops the driver. +`public void `[`qmkusbSuspendHookI`](#group___s_e_r_i_a_l___u_s_b_1gad59935eea3dab7a0584fd759c884e814)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | USB device suspend handler. +`public void `[`qmkusbWakeupHookI`](#group___s_e_r_i_a_l___u_s_b_1ga9bc8dd88462d0e3b39f7fdfec2c3ee55)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | USB device wakeup handler. +`public void `[`qmkusbConfigureHookI`](#group___s_e_r_i_a_l___u_s_b_1ga920acd9f8890b819614515b73923b72f)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | USB device configured handler. +`public bool `[`qmkusbRequestsHook`](#group___s_e_r_i_a_l___u_s_b_1gabae5bdec8abeac31be61c976301c37ba)`(USBDriver * usbp)` | Default requests hook. +`public void `[`qmkusbSOFHookI`](#group___s_e_r_i_a_l___u_s_b_1ga6db1c065c87835f96ffa248b80dbf381)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` | SOF handler. +`public void `[`qmkusbDataTransmitted`](#group___s_e_r_i_a_l___u_s_b_1ga2baecc9d4f4ec49c7e26b5dd0740c7cd)`(USBDriver * usbp,usbep_t ep)` | Default data transmitted callback. +`public void `[`qmkusbDataReceived`](#group___s_e_r_i_a_l___u_s_b_1gafb6e37d8a2dd4fe37aabf86d18275546)`(USBDriver * usbp,usbep_t ep)` | Default data received callback. +`public void `[`qmkusbInterruptTransmitted`](#group___s_e_r_i_a_l___u_s_b_1ga67ee1fd2c4129831dc15194d5284cf52)`(USBDriver * usbp,usbep_t ep)` | Default data received callback. +`struct `[`QMKUSBConfig`](#struct_q_m_k_u_s_b_config) | Serial over USB Driver configuration structure. +`struct `[`QMKUSBDriverVMT`](#struct_q_m_k_u_s_b_driver_v_m_t) | `SerialDriver` virtual methods table. +`struct `[`QMKUSBDriver`](#struct_q_m_k_u_s_b_driver) | Full duplex serial driver class. + +## Members + +#### `define `[`_qmk_usb_driver_data`](#group___s_e_r_i_a_l___u_s_b_1ga623f2c1e20bb296cf3cbdc88d153b6c9) {#group___s_e_r_i_a_l___u_s_b_1ga623f2c1e20bb296cf3cbdc88d153b6c9} + +`SerialDriver` specific data. + +#### `define `[`_qmk_usb_driver_methods`](#group___s_e_r_i_a_l___u_s_b_1ga798bce936d06cb5332a1c0e545b84dbb) {#group___s_e_r_i_a_l___u_s_b_1ga798bce936d06cb5332a1c0e545b84dbb} + +`SerialUSBDriver` specific methods. + +#### `enum `[`qmkusbstate_t`](#group___s_e_r_i_a_l___u_s_b_1ga534e1c5933a7c4785f5882ad21674302) {#group___s_e_r_i_a_l___u_s_b_1ga534e1c5933a7c4785f5882ad21674302} + + Values | Descriptions +--------------------------------|--------------------------------------------- +QMKUSB_UNINIT | Not initialized. +QMKUSB_STOP | Stopped. +QMKUSB_READY | Ready. + +Driver state machine possible states. + +#### `public static bool `[`qmkusb_start_receive`](#group___s_e_r_i_a_l___u_s_b_1ga4a2db2450b14c2a07c681b5d9429d76e)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1ga4a2db2450b14c2a07c681b5d9429d76e} + +#### `public static size_t `[`_write`](#group___s_e_r_i_a_l___u_s_b_1ga5e8117f4f91892c3d46076b0853b9116)`(void * ip,const uint8_t * bp,size_t n)` {#group___s_e_r_i_a_l___u_s_b_1ga5e8117f4f91892c3d46076b0853b9116} + +#### `public static size_t `[`_read`](#group___s_e_r_i_a_l___u_s_b_1gac07ed241c806363b6d298d7b4e2c3dad)`(void * ip,uint8_t * bp,size_t n)` {#group___s_e_r_i_a_l___u_s_b_1gac07ed241c806363b6d298d7b4e2c3dad} + +#### `public static msg_t `[`_put`](#group___s_e_r_i_a_l___u_s_b_1ga240a53ff8cbb972b8e9ccdd4cdbcaedd)`(void * ip,uint8_t b)` {#group___s_e_r_i_a_l___u_s_b_1ga240a53ff8cbb972b8e9ccdd4cdbcaedd} + +#### `public static msg_t `[`_get`](#group___s_e_r_i_a_l___u_s_b_1ga0ef118239efc83deca980513e7330658)`(void * ip)` {#group___s_e_r_i_a_l___u_s_b_1ga0ef118239efc83deca980513e7330658} + +#### `public static msg_t `[`_putt`](#group___s_e_r_i_a_l___u_s_b_1ga63abfd1c739742e5ae219f15824e47ca)`(void * ip,uint8_t b,sysinterval_t timeout)` {#group___s_e_r_i_a_l___u_s_b_1ga63abfd1c739742e5ae219f15824e47ca} + +#### `public static msg_t `[`_gett`](#group___s_e_r_i_a_l___u_s_b_1ga122f8c98aa183cf27022ea53a7cac4d5)`(void * ip,sysinterval_t timeout)` {#group___s_e_r_i_a_l___u_s_b_1ga122f8c98aa183cf27022ea53a7cac4d5} + +#### `public static size_t `[`_writet`](#group___s_e_r_i_a_l___u_s_b_1ga015a4300ed5207dec4541348a9a04671)`(void * ip,const uint8_t * bp,size_t n,sysinterval_t timeout)` {#group___s_e_r_i_a_l___u_s_b_1ga015a4300ed5207dec4541348a9a04671} + +#### `public static size_t `[`_readt`](#group___s_e_r_i_a_l___u_s_b_1ga87af5dde7865331b7634b63a3b004914)`(void * ip,uint8_t * bp,size_t n,sysinterval_t timeout)` {#group___s_e_r_i_a_l___u_s_b_1ga87af5dde7865331b7634b63a3b004914} + +#### `public static void `[`ibnotify`](#group___s_e_r_i_a_l___u_s_b_1ga278a0b24aa52959889f37ab7e8041698)`(io_buffers_queue_t * bqp)` {#group___s_e_r_i_a_l___u_s_b_1ga278a0b24aa52959889f37ab7e8041698} + +Notification of empty buffer released into the input buffers queue. + +#### Parameters +* `bqp` the buffers queue pointer. + +#### `public static void `[`obnotify`](#group___s_e_r_i_a_l___u_s_b_1gaf0e8ad9d01f2cbe14aa5a4e49f099547)`(io_buffers_queue_t * bqp)` {#group___s_e_r_i_a_l___u_s_b_1gaf0e8ad9d01f2cbe14aa5a4e49f099547} + +Notification of filled buffer inserted into the output buffers queue. + +#### Parameters +* `bqp` the buffers queue pointer. + +#### `public void `[`qmkusbInit`](#group___s_e_r_i_a_l___u_s_b_1ga3853659326b42a6df413177ff65d7c15)`(void)` {#group___s_e_r_i_a_l___u_s_b_1ga3853659326b42a6df413177ff65d7c15} + +Serial Driver initialization. + +This function is implicitly invoked by `halInit()`, there is no need to explicitly initialize the driver. + +#### `public void `[`qmkusbObjectInit`](#group___s_e_r_i_a_l___u_s_b_1gaf8ba926d88993cb4fab100f1ef427e0b)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp,const `[`QMKUSBConfig`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_config)` * config)` {#group___s_e_r_i_a_l___u_s_b_1gaf8ba926d88993cb4fab100f1ef427e0b} + +Initializes a generic full duplex driver object. + +The HW dependent part of the initialization has to be performed outside, usually in the hardware initialization code. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` structure + +#### `public void `[`qmkusbStart`](#group___s_e_r_i_a_l___u_s_b_1ga82f3c032f7fb6832a60d6048f69c3e3d)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp,const `[`QMKUSBConfig`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_config)` * config)` {#group___s_e_r_i_a_l___u_s_b_1ga82f3c032f7fb6832a60d6048f69c3e3d} + +Configures and starts the driver. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +* `config` the serial over USB driver configuration + +#### `public void `[`qmkusbStop`](#group___s_e_r_i_a_l___u_s_b_1gaa032aca2a467800dc0dc0e205b4757d5)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1gaa032aca2a467800dc0dc0e205b4757d5} + +Stops the driver. + +Any thread waiting on the driver's queues will be awakened with the message `MSG_RESET`. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +#### `public void `[`qmkusbSuspendHookI`](#group___s_e_r_i_a_l___u_s_b_1gad59935eea3dab7a0584fd759c884e814)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1gad59935eea3dab7a0584fd759c884e814} + +USB device suspend handler. + +Generates a `CHN_DISCONNECT` event and puts queues in non-blocking mode, this way the application cannot get stuck in the middle of an I/O operations. If this function is not called from an ISR then an explicit call to `osalOsRescheduleS()` in necessary afterward. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +#### `public void `[`qmkusbWakeupHookI`](#group___s_e_r_i_a_l___u_s_b_1ga9bc8dd88462d0e3b39f7fdfec2c3ee55)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1ga9bc8dd88462d0e3b39f7fdfec2c3ee55} + +USB device wakeup handler. + +Generates a `CHN_CONNECT` event and resumes normal queues operations. + +If this function is not called from an ISR then an explicit call to `osalOsRescheduleS()` in necessary afterward. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +#### `public void `[`qmkusbConfigureHookI`](#group___s_e_r_i_a_l___u_s_b_1ga920acd9f8890b819614515b73923b72f)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1ga920acd9f8890b819614515b73923b72f} + +USB device configured handler. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +#### `public bool `[`qmkusbRequestsHook`](#group___s_e_r_i_a_l___u_s_b_1gabae5bdec8abeac31be61c976301c37ba)`(USBDriver * usbp)` {#group___s_e_r_i_a_l___u_s_b_1gabae5bdec8abeac31be61c976301c37ba} + +Default requests hook. + +Applications wanting to use the Serial over USB driver can use this function as requests hook in the USB configuration. The following requests are emulated: + +* CDC_GET_LINE_CODING. + +* CDC_SET_LINE_CODING. + +* CDC_SET_CONTROL_LINE_STATE. + +#### Parameters +* `usbp` pointer to the `USBDriver` object + +#### Returns +The hook status. + +#### Parameters +* `true` Message handled internally. + +* `false` Message not handled. + +#### `public void `[`qmkusbSOFHookI`](#group___s_e_r_i_a_l___u_s_b_1ga6db1c065c87835f96ffa248b80dbf381)`(`[`QMKUSBDriver`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` * qmkusbp)` {#group___s_e_r_i_a_l___u_s_b_1ga6db1c065c87835f96ffa248b80dbf381} + +SOF handler. + +The SOF interrupt is used for automatic flushing of incomplete buffers pending in the output queue. + +#### Parameters +* `qmkusbp` pointer to a `[QMKUSBDriver](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver)` object + +#### `public void `[`qmkusbDataTransmitted`](#group___s_e_r_i_a_l___u_s_b_1ga2baecc9d4f4ec49c7e26b5dd0740c7cd)`(USBDriver * usbp,usbep_t ep)` {#group___s_e_r_i_a_l___u_s_b_1ga2baecc9d4f4ec49c7e26b5dd0740c7cd} + +Default data transmitted callback. + +The application must use this function as callback for the IN data endpoint. + +#### Parameters +* `usbp` pointer to the `USBDriver` object + +* `ep` IN endpoint number + +#### `public void `[`qmkusbDataReceived`](#group___s_e_r_i_a_l___u_s_b_1gafb6e37d8a2dd4fe37aabf86d18275546)`(USBDriver * usbp,usbep_t ep)` {#group___s_e_r_i_a_l___u_s_b_1gafb6e37d8a2dd4fe37aabf86d18275546} + +Default data received callback. + +The application must use this function as callback for the OUT data endpoint. + +#### Parameters +* `usbp` pointer to the `USBDriver` object + +* `ep` OUT endpoint number + +#### `public void `[`qmkusbInterruptTransmitted`](#group___s_e_r_i_a_l___u_s_b_1ga67ee1fd2c4129831dc15194d5284cf52)`(USBDriver * usbp,usbep_t ep)` {#group___s_e_r_i_a_l___u_s_b_1ga67ee1fd2c4129831dc15194d5284cf52} + +Default data received callback. + +The application must use this function as callback for the IN interrupt endpoint. + +#### Parameters +* `usbp` pointer to the `USBDriver` object + +* `ep` endpoint number + +# struct `QMKUSBConfig` {#struct_q_m_k_u_s_b_config} + +Serial over USB Driver configuration structure. + +An instance of this structure must be passed to `sduStart()` in order to configure and start the driver operations. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public USBDriver * `[`usbp`](#struct_q_m_k_u_s_b_config_1ada1ea0b2aba306995949dbaa24fdf71d) | USB driver to use. +`public usbep_t `[`bulk_in`](#struct_q_m_k_u_s_b_config_1afa43b7b434054546af9f4ec651c5f97e) | Bulk IN endpoint used for outgoing data transfer. +`public usbep_t `[`bulk_out`](#struct_q_m_k_u_s_b_config_1a88cf95319b2e27fb5bcdb6d3bb116ba5) | Bulk OUT endpoint used for incoming data transfer. +`public usbep_t `[`int_in`](#struct_q_m_k_u_s_b_config_1a475ce337f1cac40f24657c2030a2f268) | Interrupt IN endpoint used for notifications. +`public size_t `[`in_buffers`](#struct_q_m_k_u_s_b_config_1a983983e0ca22143fd32e8dc3383c174e) | The number of buffers in the queues. +`public size_t `[`out_buffers`](#struct_q_m_k_u_s_b_config_1a481eeab48689523b99a95e1666b2cb96) | +`public size_t `[`in_size`](#struct_q_m_k_u_s_b_config_1a600c0d75ca3fa7bafc2e38ce9bb0bf6e) | The size of each buffer in the queue, typically the same as the endpoint size. +`public size_t `[`out_size`](#struct_q_m_k_u_s_b_config_1ac5e66af2f4fed2cf04fcbd77f1114bfb) | +`public bool `[`fixed_size`](#struct_q_m_k_u_s_b_config_1ad90e1bf1d310f5fbf5e8ce49b596f94b) | Always send full buffers in_size (the rest is filled with zeroes) +`public uint8_t * `[`ib`](#struct_q_m_k_u_s_b_config_1ae3be5d8a14227ab7003a9523994cae54) | +`public uint8_t * `[`ob`](#struct_q_m_k_u_s_b_config_1a66f479912494377c5a80dc78ac2702cc) | + +## Members + +#### `public USBDriver * `[`usbp`](#struct_q_m_k_u_s_b_config_1ada1ea0b2aba306995949dbaa24fdf71d) {#struct_q_m_k_u_s_b_config_1ada1ea0b2aba306995949dbaa24fdf71d} + +USB driver to use. + +#### `public usbep_t `[`bulk_in`](#struct_q_m_k_u_s_b_config_1afa43b7b434054546af9f4ec651c5f97e) {#struct_q_m_k_u_s_b_config_1afa43b7b434054546af9f4ec651c5f97e} + +Bulk IN endpoint used for outgoing data transfer. + +#### `public usbep_t `[`bulk_out`](#struct_q_m_k_u_s_b_config_1a88cf95319b2e27fb5bcdb6d3bb116ba5) {#struct_q_m_k_u_s_b_config_1a88cf95319b2e27fb5bcdb6d3bb116ba5} + +Bulk OUT endpoint used for incoming data transfer. + +#### `public usbep_t `[`int_in`](#struct_q_m_k_u_s_b_config_1a475ce337f1cac40f24657c2030a2f268) {#struct_q_m_k_u_s_b_config_1a475ce337f1cac40f24657c2030a2f268} + +Interrupt IN endpoint used for notifications. + +If set to zero then the INT endpoint is assumed to be not present, USB descriptors must be changed accordingly. + +#### `public size_t `[`in_buffers`](#struct_q_m_k_u_s_b_config_1a983983e0ca22143fd32e8dc3383c174e) {#struct_q_m_k_u_s_b_config_1a983983e0ca22143fd32e8dc3383c174e} + +The number of buffers in the queues. + +#### `public size_t `[`out_buffers`](#struct_q_m_k_u_s_b_config_1a481eeab48689523b99a95e1666b2cb96) {#struct_q_m_k_u_s_b_config_1a481eeab48689523b99a95e1666b2cb96} + +#### `public size_t `[`in_size`](#struct_q_m_k_u_s_b_config_1a600c0d75ca3fa7bafc2e38ce9bb0bf6e) {#struct_q_m_k_u_s_b_config_1a600c0d75ca3fa7bafc2e38ce9bb0bf6e} + +The size of each buffer in the queue, typically the same as the endpoint size. + +#### `public size_t `[`out_size`](#struct_q_m_k_u_s_b_config_1ac5e66af2f4fed2cf04fcbd77f1114bfb) {#struct_q_m_k_u_s_b_config_1ac5e66af2f4fed2cf04fcbd77f1114bfb} + +#### `public bool `[`fixed_size`](#struct_q_m_k_u_s_b_config_1ad90e1bf1d310f5fbf5e8ce49b596f94b) {#struct_q_m_k_u_s_b_config_1ad90e1bf1d310f5fbf5e8ce49b596f94b} + +Always send full buffers in_size (the rest is filled with zeroes) + +#### `public uint8_t * `[`ib`](#struct_q_m_k_u_s_b_config_1ae3be5d8a14227ab7003a9523994cae54) {#struct_q_m_k_u_s_b_config_1ae3be5d8a14227ab7003a9523994cae54} + +#### `public uint8_t * `[`ob`](#struct_q_m_k_u_s_b_config_1a66f479912494377c5a80dc78ac2702cc) {#struct_q_m_k_u_s_b_config_1a66f479912494377c5a80dc78ac2702cc} + +# struct `QMKUSBDriverVMT` {#struct_q_m_k_u_s_b_driver_v_m_t} + +``` +struct QMKUSBDriverVMT + : public BaseAsynchronousChannelVMT +``` + +`SerialDriver` virtual methods table. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + +## Members + +# struct `QMKUSBDriver` {#struct_q_m_k_u_s_b_driver} + +``` +struct QMKUSBDriver + : public BaseAsynchronousChannel +``` + +Full duplex serial driver class. + +This class extends `BaseAsynchronousChannel` by adding physical I/O queues. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public const struct `[`QMKUSBDriverVMT`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver_v_m_t)` * `[`vmt`](#struct_q_m_k_u_s_b_driver_1aa84464b0edad252f9f93af83c669501e) | Virtual Methods Table. + +## Members + +#### `public const struct `[`QMKUSBDriverVMT`](.build/docs/internals_SERIAL_USB.md#struct_q_m_k_u_s_b_driver_v_m_t)` * `[`vmt`](#struct_q_m_k_u_s_b_driver_1aa84464b0edad252f9f93af83c669501e) {#struct_q_m_k_u_s_b_driver_1aa84464b0edad252f9f93af83c669501e} + +Virtual Methods Table. + diff --git a/internals_asfdoc_sam0_usb_group.md b/internals_asfdoc_sam0_usb_group.md new file mode 100644 index 00000000000..7de8fc8d74d --- /dev/null +++ b/internals_asfdoc_sam0_usb_group.md @@ -0,0 +1,25 @@ +# group `asfdoc_sam0_usb_group` {#group__asfdoc__sam0__usb__group} + +The Universal Serial Bus (USB) module complies with the USB 2.1 specification. + +The following peripherals are used by this module: + +* USB (Universal Serial Bus) + +The following devices can use this module: + +* Atmel | SMART SAM D51 + +The USB module covers following mode: + +The USB module covers following speed: + +* USB Full Speed (12Mbit/s) + +USB support needs whole set of enumeration process, to make the device recognizable and usable. The USB driver is designed to interface to the USB Stack in Atmel Software Framework (ASF). + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_defines.md b/internals_defines.md new file mode 100644 index 00000000000..fdcb553589b --- /dev/null +++ b/internals_defines.md @@ -0,0 +1,78 @@ +# group `defines` {#group__defines} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`SYSEX_BEGIN`](#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79) | +`define `[`SYSEX_END`](#group__defines_1ga753706d1d28e6f96d7caf1973e80feed) | +`define `[`MIDI_STATUSMASK`](#group__defines_1gab78a1c818a5f5dab7a8946543f126c69) | +`define `[`MIDI_CHANMASK`](#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909) | +`define `[`MIDI_CC`](#group__defines_1ga45f116a1daab76b3c930c2cecfaef215) | +`define `[`MIDI_NOTEON`](#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7) | +`define `[`MIDI_NOTEOFF`](#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc) | +`define `[`MIDI_AFTERTOUCH`](#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f) | +`define `[`MIDI_PITCHBEND`](#group__defines_1gabcc799504e8064679bca03f232223af4) | +`define `[`MIDI_PROGCHANGE`](#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42) | +`define `[`MIDI_CHANPRESSURE`](#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe) | +`define `[`MIDI_CLOCK`](#group__defines_1gafa5e4e295aafd15ab7893344599b3b89) | +`define `[`MIDI_TICK`](#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7) | +`define `[`MIDI_START`](#group__defines_1ga8233631c85823aa546f932ad8975caa4) | +`define `[`MIDI_CONTINUE`](#group__defines_1gab24430f0081e27215b0da84dd0ee745c) | +`define `[`MIDI_STOP`](#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62) | +`define `[`MIDI_ACTIVESENSE`](#group__defines_1gacd88ed42dba52bb4b2052c5656362677) | +`define `[`MIDI_RESET`](#group__defines_1ga02947f30ca62dc332fdeb10c5868323b) | +`define `[`MIDI_TC_QUARTERFRAME`](#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31) | +`define `[`MIDI_SONGPOSITION`](#group__defines_1ga412f6ed33a2150051374bee334ee1705) | +`define `[`MIDI_SONGSELECT`](#group__defines_1gafcab254838b028365ae0259729e72c4e) | +`define `[`MIDI_TUNEREQUEST`](#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795) | +`define `[`SYSEX_EDUMANUFID`](#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f) | + +## Members + +#### `define `[`SYSEX_BEGIN`](#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79) {#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79} + +#### `define `[`SYSEX_END`](#group__defines_1ga753706d1d28e6f96d7caf1973e80feed) {#group__defines_1ga753706d1d28e6f96d7caf1973e80feed} + +#### `define `[`MIDI_STATUSMASK`](#group__defines_1gab78a1c818a5f5dab7a8946543f126c69) {#group__defines_1gab78a1c818a5f5dab7a8946543f126c69} + +#### `define `[`MIDI_CHANMASK`](#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909) {#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909} + +#### `define `[`MIDI_CC`](#group__defines_1ga45f116a1daab76b3c930c2cecfaef215) {#group__defines_1ga45f116a1daab76b3c930c2cecfaef215} + +#### `define `[`MIDI_NOTEON`](#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7) {#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7} + +#### `define `[`MIDI_NOTEOFF`](#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc) {#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc} + +#### `define `[`MIDI_AFTERTOUCH`](#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f) {#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f} + +#### `define `[`MIDI_PITCHBEND`](#group__defines_1gabcc799504e8064679bca03f232223af4) {#group__defines_1gabcc799504e8064679bca03f232223af4} + +#### `define `[`MIDI_PROGCHANGE`](#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42) {#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42} + +#### `define `[`MIDI_CHANPRESSURE`](#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe) {#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe} + +#### `define `[`MIDI_CLOCK`](#group__defines_1gafa5e4e295aafd15ab7893344599b3b89) {#group__defines_1gafa5e4e295aafd15ab7893344599b3b89} + +#### `define `[`MIDI_TICK`](#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7) {#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7} + +#### `define `[`MIDI_START`](#group__defines_1ga8233631c85823aa546f932ad8975caa4) {#group__defines_1ga8233631c85823aa546f932ad8975caa4} + +#### `define `[`MIDI_CONTINUE`](#group__defines_1gab24430f0081e27215b0da84dd0ee745c) {#group__defines_1gab24430f0081e27215b0da84dd0ee745c} + +#### `define `[`MIDI_STOP`](#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62) {#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62} + +#### `define `[`MIDI_ACTIVESENSE`](#group__defines_1gacd88ed42dba52bb4b2052c5656362677) {#group__defines_1gacd88ed42dba52bb4b2052c5656362677} + +#### `define `[`MIDI_RESET`](#group__defines_1ga02947f30ca62dc332fdeb10c5868323b) {#group__defines_1ga02947f30ca62dc332fdeb10c5868323b} + +#### `define `[`MIDI_TC_QUARTERFRAME`](#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31) {#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31} + +#### `define `[`MIDI_SONGPOSITION`](#group__defines_1ga412f6ed33a2150051374bee334ee1705) {#group__defines_1ga412f6ed33a2150051374bee334ee1705} + +#### `define `[`MIDI_SONGSELECT`](#group__defines_1gafcab254838b028365ae0259729e72c4e) {#group__defines_1gafcab254838b028365ae0259729e72c4e} + +#### `define `[`MIDI_TUNEREQUEST`](#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795) {#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795} + +#### `define `[`SYSEX_EDUMANUFID`](#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f) {#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f} + diff --git a/internals_gpio_control.md b/internals_gpio_control.md new file mode 100644 index 00000000000..48eaf8875b7 --- /dev/null +++ b/internals_gpio_control.md @@ -0,0 +1,23 @@ +# GPIO Control :id=gpio-control + +QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms. + +## Functions :id=functions + +The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`. + +|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples | +|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------| +| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | +| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | +| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | +| `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | +| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | +| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | +| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | +| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | +| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | + +## Advanced Settings :id=advanced-settings + +Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used. diff --git a/internals_group_sam0_utils.md b/internals_group_sam0_utils.md new file mode 100644 index 00000000000..702f38ef2af --- /dev/null +++ b/internals_group_sam0_utils.md @@ -0,0 +1,571 @@ +# group `group_sam0_utils` {#group__group__sam0__utils} + +Compiler abstraction layer and code utilities for Cortex-M0+ based Atmel SAM devices. This module provides various abstraction layers and utilities to make code compatible between different compilers. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`UNUSED`](#group__group__sam0__utils_1gada67c62b1c57e07efa04431bc40b9238) | Marking *v* as a unused parameter or value. +`define `[`barrier`](#group__group__sam0__utils_1ga53290ac2df2384738b8769c76622f803) | Memory barrier. +`define `[`COMPILER_PRAGMA`](#group__group__sam0__utils_1ga85a3ab5701281268521f109ed0078668) | Emit the compiler pragma *arg*. +`define `[`COMPILER_PACK_SET`](#group__group__sam0__utils_1gae2c02ff865ca6538b4b1bddbf2a6876c) | Set maximum alignment for subsequent struct and union definitions to *alignment*. +`define `[`COMPILER_PACK_RESET`](#group__group__sam0__utils_1ga38d28b622a4bc7b0f3fb2be2ef1e0086) | Set default alignment for subsequent struct and union definitions. +`define `[`Assert`](#group__group__sam0__utils_1gaab1e54dcc40192f9704e8b252635450f) | This macro is used to test fatal errors. +`define `[`Long_call`](#group__group__sam0__utils_1ga5b759626f343cc1af9159cc02b763837) | Calls the routine at address *addr*. +`define `[`div_ceil`](#group__group__sam0__utils_1ga6d4ebd841bc96041a7f3a61e227c1fb2) | Calculate $ \left\lceil \frac{a}{b} \right\rceil $ using integer arithmetic. +`define `[`FUNC_PTR`](#group__group__sam0__utils_1gacce64924b686dd08a83042b35d0d1480) | +`define `[`unused`](#group__group__sam0__utils_1ga417dba7f63dde98dbebd6336d8af9d91) | Marking *v* as a unused parameter or value. +`define `[`MSB`](#group__group__sam0__utils_1gabee1b74eceef5a0cf26efbf3ff87ccbf) | Most significant byte of *u16*. +`define `[`LSB`](#group__group__sam0__utils_1gabd2fa7b756342ae251e3a7a66670c2fe) | Least significant byte of *u16*. +`define `[`MSH`](#group__group__sam0__utils_1ga2e9046f49816ad27148660f5ba993696) | Most significant half-word of *u32*. +`define `[`LSH`](#group__group__sam0__utils_1gae79954742b5a668ce83ab79ac9d9804b) | Least significant half-word of *u32*. +`define `[`MSB0W`](#group__group__sam0__utils_1ga25110f05bdb5b5ea3fcb2854a1a07d7a) | Most significant byte of 1st rank of *u32*. +`define `[`MSB1W`](#group__group__sam0__utils_1ga0f90ecd0b0f0e15608a95b8367b77ece) | Most significant byte of 2nd rank of *u32*. +`define `[`MSB2W`](#group__group__sam0__utils_1ga0207e10a3c4bcca172463cd5e3ebd865) | Most significant byte of 3rd rank of *u32*. +`define `[`MSB3W`](#group__group__sam0__utils_1gad6ab5ac6e3e95525d56d757c9718e352) | Most significant byte of 4th rank of *u32*. +`define `[`LSB3W`](#group__group__sam0__utils_1ga04e75e548b33b9cc22699b4249ff6c64) | Least significant byte of 4th rank of *u32*. +`define `[`LSB2W`](#group__group__sam0__utils_1gad8fda97f8caa00fcfa84f712ee7627d6) | Least significant byte of 3rd rank of *u32*. +`define `[`LSB1W`](#group__group__sam0__utils_1ga84cbbcad1971cdb2987418e6ae6cb4ff) | Least significant byte of 2nd rank of *u32*. +`define `[`LSB0W`](#group__group__sam0__utils_1ga2ca8582260a8ada6cdd457cf37ba37a7) | Least significant byte of 1st rank of *u32*. +`define `[`MSW`](#group__group__sam0__utils_1gad71e5e84d2cec4387415a55f5c62b01b) | Most significant word of *u64*. +`define `[`LSW`](#group__group__sam0__utils_1ga0633993fb1f2d96a56385f09beed7bc7) | Least significant word of *u64*. +`define `[`MSH0`](#group__group__sam0__utils_1ga280d6a94884872f6a5be80c873e8adc1) | Most significant half-word of 1st rank of *u64*. +`define `[`MSH1`](#group__group__sam0__utils_1ga43de4fac62f938ff4eb448a87522ec0e) | Most significant half-word of 2nd rank of *u64*. +`define `[`MSH2`](#group__group__sam0__utils_1ga5d32ec744212194c8106c51b89a5dfe9) | Most significant half-word of 3rd rank of *u64*. +`define `[`MSH3`](#group__group__sam0__utils_1gabb233f238b63c12d2ff361d9ddb3114b) | Most significant half-word of 4th rank of *u64*. +`define `[`LSH3`](#group__group__sam0__utils_1ga1ec33d340ef17c91cb0530d00ccb0ea8) | Least significant half-word of 4th rank of *u64*. +`define `[`LSH2`](#group__group__sam0__utils_1ga2efccfe683ebf7d89a972fbbdea2c26d) | Least significant half-word of 3rd rank of *u64*. +`define `[`LSH1`](#group__group__sam0__utils_1gac593b0be4555d883b4297b45cffc4168) | Least significant half-word of 2nd rank of *u64*. +`define `[`LSH0`](#group__group__sam0__utils_1ga3026b9288b45a9794fd3eb585cbe10bc) | Least significant half-word of 1st rank of *u64*. +`define `[`MSB0D`](#group__group__sam0__utils_1ga5f24ecf381776ee415991a545a05e4c7) | Most significant byte of 1st rank of *u64*. +`define `[`MSB1D`](#group__group__sam0__utils_1ga97a0ab6790df95cb4d8021d8850487f8) | Most significant byte of 2nd rank of *u64*. +`define `[`MSB2D`](#group__group__sam0__utils_1gad4ceacba543e7b8617ca4bd075abb146) | Most significant byte of 3rd rank of *u64*. +`define `[`MSB3D`](#group__group__sam0__utils_1gaf7972d3282ec9ecb97afa34e848ede2c) | Most significant byte of 4th rank of *u64*. +`define `[`MSB4D`](#group__group__sam0__utils_1ga1c891624c33b13808633af8dbcaafa5f) | Most significant byte of 5th rank of *u64*. +`define `[`MSB5D`](#group__group__sam0__utils_1ga5e61db58aaf5cbb3051240cdcb1b5147) | Most significant byte of 6th rank of *u64*. +`define `[`MSB6D`](#group__group__sam0__utils_1gacb8062d046ca06f5c28c9a015997494b) | Most significant byte of 7th rank of *u64*. +`define `[`MSB7D`](#group__group__sam0__utils_1ga0cbce69964fa2dd7bf05911d0b99b014) | Most significant byte of 8th rank of *u64*. +`define `[`LSB7D`](#group__group__sam0__utils_1ga79fb849e13082fdd4adb02debbad7f1a) | Least significant byte of 8th rank of *u64*. +`define `[`LSB6D`](#group__group__sam0__utils_1gab90afefaf3b5cb2507ab3c496d8f643c) | Least significant byte of 7th rank of *u64*. +`define `[`LSB5D`](#group__group__sam0__utils_1gac379acb246797736332fa1b8ae481b34) | Least significant byte of 6th rank of *u64*. +`define `[`LSB4D`](#group__group__sam0__utils_1gaab745f30b9b841f9ccd9ace0a5a1a9e5) | Least significant byte of 5th rank of *u64*. +`define `[`LSB3D`](#group__group__sam0__utils_1ga99213c01b979c347950eba4277f0499a) | Least significant byte of 4th rank of *u64*. +`define `[`LSB2D`](#group__group__sam0__utils_1gaba3bea07dcc4a37039b7effd4da03b9e) | Least significant byte of 3rd rank of *u64*. +`define `[`LSB1D`](#group__group__sam0__utils_1ga42179f159b798116eb615102a549aa85) | Least significant byte of 2nd rank of *u64*. +`define `[`LSB0D`](#group__group__sam0__utils_1ga2e20f5ef87ccf0ad44c1d49d6ffd80a3) | Least significant byte of 1st rank of *u64*. +`define `[`LSB0`](#group__group__sam0__utils_1ga844ec34df36feb927dc92007af14674a) | Least significant byte of 1st rank of *u32*. +`define `[`LSB1`](#group__group__sam0__utils_1ga2d1e45154b07481f0579ecc725e4edff) | Least significant byte of 2nd rank of *u32*. +`define `[`LSB2`](#group__group__sam0__utils_1ga8967f5ae0174b01ce44c502ebd14035a) | Least significant byte of 3rd rank of *u32*. +`define `[`LSB3`](#group__group__sam0__utils_1ga5d9ff393e7c8764112a1167db19b16b1) | Least significant byte of 4th rank of *u32*. +`define `[`MSB3`](#group__group__sam0__utils_1gaeeb8918fc580ce01d45f71863eebff90) | Most significant byte of 4th rank of *u32*. +`define `[`MSB2`](#group__group__sam0__utils_1ga8683254be29bcfe3cf2fa646890d3942) | Most significant byte of 3rd rank of *u32*. +`define `[`MSB1`](#group__group__sam0__utils_1ga3facab9f8ebf70ad6e16038465e2bedc) | Most significant byte of 2nd rank of *u32*. +`define `[`MSB0`](#group__group__sam0__utils_1gafb81783b8186acd7182a971048b0c6b3) | Most significant byte of 1st rank of *u32*. +`define `[`FLASH_DECLARE`](#group__group__sam0__utils_1ga9b84ecc6b34a71f797ceb8b8f7b8d384) | +`define `[`FLASH_EXTERN`](#group__group__sam0__utils_1gaaef0fd990bb5bd9cdf11334f7c689fd7) | +`define `[`PGM_READ_BYTE`](#group__group__sam0__utils_1gafe9b83c73d4840986478ec67d3eb7718) | +`define `[`PGM_READ_WORD`](#group__group__sam0__utils_1ga92576bffe51090dcb6d5c67e07b9eec7) | +`define `[`MEMCPY_ENDIAN`](#group__group__sam0__utils_1ga85a7d71a016789b1766f9b27d0530347) | +`define `[`PGM_READ_BLOCK`](#group__group__sam0__utils_1ga8900e4615b7d7143a6c38e2a39087538) | +`define `[`CMD_ID_OCTET`](#group__group__sam0__utils_1gabf2b95fa77301377cdcf79eb615551db) | +`define `[`CPU_ENDIAN_TO_LE16`](#group__group__sam0__utils_1ga7c15ca0f3159182efc4b80a00768c2c0) | +`define `[`CPU_ENDIAN_TO_LE32`](#group__group__sam0__utils_1gaa2fd4bfb7af44220ce4205e2aa371017) | +`define `[`CPU_ENDIAN_TO_LE64`](#group__group__sam0__utils_1ga6f1e86f452c8f327f9ca96cbf6a65c81) | +`define `[`LE16_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gaceb02fdef243c22d2559e260185fb579) | +`define `[`LE32_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga2df63369ef525ba98832132ce5a43346) | +`define `[`LE64_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gab675071ce5a4644b205cdbc858417ccd) | +`define `[`CLE16_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga4ac6e032d1ce0ae6d2e460da93ce8732) | +`define `[`CLE32_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga3ff07a7496222efe8bc7d7b7b0342b0d) | +`define `[`CLE64_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gacbbba93256e2d892c748d56a42f00f9b) | +`define `[`CCPU_ENDIAN_TO_LE16`](#group__group__sam0__utils_1ga5fd2d3ed2fc9234277b659b67d33bc64) | +`define `[`CCPU_ENDIAN_TO_LE32`](#group__group__sam0__utils_1ga1e3290451e5c7b98175911c9219b5123) | +`define `[`CCPU_ENDIAN_TO_LE64`](#group__group__sam0__utils_1ga00483bf27ea1e8a2143c6baf22b31f16) | +`define `[`ADDR_COPY_DST_SRC_16`](#group__group__sam0__utils_1gac4609178e5c825e815f44fa123dcaaf7) | +`define `[`ADDR_COPY_DST_SRC_64`](#group__group__sam0__utils_1ga0454afa80924c2183c8c672c043440cc) | +`public inline static void `[`convert_64_bit_to_byte_array`](#group__group__sam0__utils_1gadca7cebb159c7ed180d3d07cccb74245)`(uint64_t value,uint8_t * data)` | Converts a 64-Bit value into a 8 Byte array. +`public inline static void `[`convert_16_bit_to_byte_array`](#group__group__sam0__utils_1ga2de8d131d6afca8b368486f56c911e75)`(uint16_t value,uint8_t * data)` | Converts a 16-Bit value into a 2 Byte array. +`public inline static void `[`convert_spec_16_bit_to_byte_array`](#group__group__sam0__utils_1gaa9724d81bfe44a06b0372d144cd98e36)`(uint16_t value,uint8_t * data)` | +`public inline static void `[`convert_16_bit_to_byte_address`](#group__group__sam0__utils_1ga9634f2d7292e1209fe3b83254a66c450)`(uint16_t value,uint8_t * data)` | +`public inline static uint16_t `[`convert_byte_array_to_16_bit`](#group__group__sam0__utils_1gad3726f56d0820acc7bae83993bd8897c)`(uint8_t * data)` | +`public inline static uint32_t `[`convert_byte_array_to_32_bit`](#group__group__sam0__utils_1ga6e01ed4a4718b439d295b5124ede09e3)`(uint8_t * data)` | +`public inline static uint64_t `[`convert_byte_array_to_64_bit`](#group__group__sam0__utils_1ga45ffdbdc2d7a6d1dbf91b2fe8d880347)`(uint8_t * data)` | Converts a 8 Byte array into a 64-Bit value. +`struct `[`StructPtr`](#struct_struct_ptr) | Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +`struct `[`StructVPtr`](#struct_struct_v_ptr) | Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +`struct `[`StructCPtr`](#struct_struct_c_ptr) | Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +`struct `[`StructCVPtr`](#struct_struct_c_v_ptr) | Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +`union `[`Union16`](#union_union16) | 16-bit union. +`union `[`Union32`](#union_union32) | 32-bit union. +`union `[`Union64`](#union_union64) | 64-bit union. +`union `[`UnionPtr`](#union_union_ptr) | Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +`union `[`UnionVPtr`](#union_union_v_ptr) | Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +`union `[`UnionCPtr`](#union_union_c_ptr) | Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +`union `[`UnionCVPtr`](#union_union_c_v_ptr) | Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. + +## Members + +#### `define `[`UNUSED`](#group__group__sam0__utils_1gada67c62b1c57e07efa04431bc40b9238) {#group__group__sam0__utils_1gada67c62b1c57e07efa04431bc40b9238} + +Marking *v* as a unused parameter or value. + +#### `define `[`barrier`](#group__group__sam0__utils_1ga53290ac2df2384738b8769c76622f803) {#group__group__sam0__utils_1ga53290ac2df2384738b8769c76622f803} + +Memory barrier. + +#### `define `[`COMPILER_PRAGMA`](#group__group__sam0__utils_1ga85a3ab5701281268521f109ed0078668) {#group__group__sam0__utils_1ga85a3ab5701281268521f109ed0078668} + +Emit the compiler pragma *arg*. + +#### Parameters +* `arg` The pragma directive as it would appear after *#pragma* (i.e. not stringified). + +#### `define `[`COMPILER_PACK_SET`](#group__group__sam0__utils_1gae2c02ff865ca6538b4b1bddbf2a6876c) {#group__group__sam0__utils_1gae2c02ff865ca6538b4b1bddbf2a6876c} + +Set maximum alignment for subsequent struct and union definitions to *alignment*. + +#### `define `[`COMPILER_PACK_RESET`](#group__group__sam0__utils_1ga38d28b622a4bc7b0f3fb2be2ef1e0086) {#group__group__sam0__utils_1ga38d28b622a4bc7b0f3fb2be2ef1e0086} + +Set default alignment for subsequent struct and union definitions. + +#### `define `[`Assert`](#group__group__sam0__utils_1gaab1e54dcc40192f9704e8b252635450f) {#group__group__sam0__utils_1gaab1e54dcc40192f9704e8b252635450f} + +This macro is used to test fatal errors. + +The macro tests if the expression is false. If it is, a fatal error is detected and the application hangs up. If `TEST_SUITE_DEFINE_ASSERT_MACRO` is defined, a unit test version of the macro is used, to allow execution of further tests after a false expression. + +#### Parameters +* `expr` Expression to evaluate and supposed to be nonzero. + +#### `define `[`Long_call`](#group__group__sam0__utils_1ga5b759626f343cc1af9159cc02b763837) {#group__group__sam0__utils_1ga5b759626f343cc1af9159cc02b763837} + +Calls the routine at address *addr*. + +It generates a long call opcode. + +For example, `Long_call(0x80000000)' generates a software reset on a UC3 if it is invoked from the CPU supervisor mode. + +#### Parameters +* `addr` Address of the routine to call. + +It may be used as a long jump opcode in some special cases. + +#### `define `[`div_ceil`](#group__group__sam0__utils_1ga6d4ebd841bc96041a7f3a61e227c1fb2) {#group__group__sam0__utils_1ga6d4ebd841bc96041a7f3a61e227c1fb2} + +Calculate $ \left\lceil \frac{a}{b} \right\rceil $ using integer arithmetic. + +#### Parameters +* `a` An integer + +* `b` Another integer + +#### Returns +(*a* / *b*) rounded up to the nearest integer. + +#### `define `[`FUNC_PTR`](#group__group__sam0__utils_1gacce64924b686dd08a83042b35d0d1480) {#group__group__sam0__utils_1gacce64924b686dd08a83042b35d0d1480} + +#### `define `[`unused`](#group__group__sam0__utils_1ga417dba7f63dde98dbebd6336d8af9d91) {#group__group__sam0__utils_1ga417dba7f63dde98dbebd6336d8af9d91} + +Marking *v* as a unused parameter or value. + +#### `define `[`MSB`](#group__group__sam0__utils_1gabee1b74eceef5a0cf26efbf3ff87ccbf) {#group__group__sam0__utils_1gabee1b74eceef5a0cf26efbf3ff87ccbf} + +Most significant byte of *u16*. + +#### `define `[`LSB`](#group__group__sam0__utils_1gabd2fa7b756342ae251e3a7a66670c2fe) {#group__group__sam0__utils_1gabd2fa7b756342ae251e3a7a66670c2fe} + +Least significant byte of *u16*. + +#### `define `[`MSH`](#group__group__sam0__utils_1ga2e9046f49816ad27148660f5ba993696) {#group__group__sam0__utils_1ga2e9046f49816ad27148660f5ba993696} + +Most significant half-word of *u32*. + +#### `define `[`LSH`](#group__group__sam0__utils_1gae79954742b5a668ce83ab79ac9d9804b) {#group__group__sam0__utils_1gae79954742b5a668ce83ab79ac9d9804b} + +Least significant half-word of *u32*. + +#### `define `[`MSB0W`](#group__group__sam0__utils_1ga25110f05bdb5b5ea3fcb2854a1a07d7a) {#group__group__sam0__utils_1ga25110f05bdb5b5ea3fcb2854a1a07d7a} + +Most significant byte of 1st rank of *u32*. + +#### `define `[`MSB1W`](#group__group__sam0__utils_1ga0f90ecd0b0f0e15608a95b8367b77ece) {#group__group__sam0__utils_1ga0f90ecd0b0f0e15608a95b8367b77ece} + +Most significant byte of 2nd rank of *u32*. + +#### `define `[`MSB2W`](#group__group__sam0__utils_1ga0207e10a3c4bcca172463cd5e3ebd865) {#group__group__sam0__utils_1ga0207e10a3c4bcca172463cd5e3ebd865} + +Most significant byte of 3rd rank of *u32*. + +#### `define `[`MSB3W`](#group__group__sam0__utils_1gad6ab5ac6e3e95525d56d757c9718e352) {#group__group__sam0__utils_1gad6ab5ac6e3e95525d56d757c9718e352} + +Most significant byte of 4th rank of *u32*. + +#### `define `[`LSB3W`](#group__group__sam0__utils_1ga04e75e548b33b9cc22699b4249ff6c64) {#group__group__sam0__utils_1ga04e75e548b33b9cc22699b4249ff6c64} + +Least significant byte of 4th rank of *u32*. + +#### `define `[`LSB2W`](#group__group__sam0__utils_1gad8fda97f8caa00fcfa84f712ee7627d6) {#group__group__sam0__utils_1gad8fda97f8caa00fcfa84f712ee7627d6} + +Least significant byte of 3rd rank of *u32*. + +#### `define `[`LSB1W`](#group__group__sam0__utils_1ga84cbbcad1971cdb2987418e6ae6cb4ff) {#group__group__sam0__utils_1ga84cbbcad1971cdb2987418e6ae6cb4ff} + +Least significant byte of 2nd rank of *u32*. + +#### `define `[`LSB0W`](#group__group__sam0__utils_1ga2ca8582260a8ada6cdd457cf37ba37a7) {#group__group__sam0__utils_1ga2ca8582260a8ada6cdd457cf37ba37a7} + +Least significant byte of 1st rank of *u32*. + +#### `define `[`MSW`](#group__group__sam0__utils_1gad71e5e84d2cec4387415a55f5c62b01b) {#group__group__sam0__utils_1gad71e5e84d2cec4387415a55f5c62b01b} + +Most significant word of *u64*. + +#### `define `[`LSW`](#group__group__sam0__utils_1ga0633993fb1f2d96a56385f09beed7bc7) {#group__group__sam0__utils_1ga0633993fb1f2d96a56385f09beed7bc7} + +Least significant word of *u64*. + +#### `define `[`MSH0`](#group__group__sam0__utils_1ga280d6a94884872f6a5be80c873e8adc1) {#group__group__sam0__utils_1ga280d6a94884872f6a5be80c873e8adc1} + +Most significant half-word of 1st rank of *u64*. + +#### `define `[`MSH1`](#group__group__sam0__utils_1ga43de4fac62f938ff4eb448a87522ec0e) {#group__group__sam0__utils_1ga43de4fac62f938ff4eb448a87522ec0e} + +Most significant half-word of 2nd rank of *u64*. + +#### `define `[`MSH2`](#group__group__sam0__utils_1ga5d32ec744212194c8106c51b89a5dfe9) {#group__group__sam0__utils_1ga5d32ec744212194c8106c51b89a5dfe9} + +Most significant half-word of 3rd rank of *u64*. + +#### `define `[`MSH3`](#group__group__sam0__utils_1gabb233f238b63c12d2ff361d9ddb3114b) {#group__group__sam0__utils_1gabb233f238b63c12d2ff361d9ddb3114b} + +Most significant half-word of 4th rank of *u64*. + +#### `define `[`LSH3`](#group__group__sam0__utils_1ga1ec33d340ef17c91cb0530d00ccb0ea8) {#group__group__sam0__utils_1ga1ec33d340ef17c91cb0530d00ccb0ea8} + +Least significant half-word of 4th rank of *u64*. + +#### `define `[`LSH2`](#group__group__sam0__utils_1ga2efccfe683ebf7d89a972fbbdea2c26d) {#group__group__sam0__utils_1ga2efccfe683ebf7d89a972fbbdea2c26d} + +Least significant half-word of 3rd rank of *u64*. + +#### `define `[`LSH1`](#group__group__sam0__utils_1gac593b0be4555d883b4297b45cffc4168) {#group__group__sam0__utils_1gac593b0be4555d883b4297b45cffc4168} + +Least significant half-word of 2nd rank of *u64*. + +#### `define `[`LSH0`](#group__group__sam0__utils_1ga3026b9288b45a9794fd3eb585cbe10bc) {#group__group__sam0__utils_1ga3026b9288b45a9794fd3eb585cbe10bc} + +Least significant half-word of 1st rank of *u64*. + +#### `define `[`MSB0D`](#group__group__sam0__utils_1ga5f24ecf381776ee415991a545a05e4c7) {#group__group__sam0__utils_1ga5f24ecf381776ee415991a545a05e4c7} + +Most significant byte of 1st rank of *u64*. + +#### `define `[`MSB1D`](#group__group__sam0__utils_1ga97a0ab6790df95cb4d8021d8850487f8) {#group__group__sam0__utils_1ga97a0ab6790df95cb4d8021d8850487f8} + +Most significant byte of 2nd rank of *u64*. + +#### `define `[`MSB2D`](#group__group__sam0__utils_1gad4ceacba543e7b8617ca4bd075abb146) {#group__group__sam0__utils_1gad4ceacba543e7b8617ca4bd075abb146} + +Most significant byte of 3rd rank of *u64*. + +#### `define `[`MSB3D`](#group__group__sam0__utils_1gaf7972d3282ec9ecb97afa34e848ede2c) {#group__group__sam0__utils_1gaf7972d3282ec9ecb97afa34e848ede2c} + +Most significant byte of 4th rank of *u64*. + +#### `define `[`MSB4D`](#group__group__sam0__utils_1ga1c891624c33b13808633af8dbcaafa5f) {#group__group__sam0__utils_1ga1c891624c33b13808633af8dbcaafa5f} + +Most significant byte of 5th rank of *u64*. + +#### `define `[`MSB5D`](#group__group__sam0__utils_1ga5e61db58aaf5cbb3051240cdcb1b5147) {#group__group__sam0__utils_1ga5e61db58aaf5cbb3051240cdcb1b5147} + +Most significant byte of 6th rank of *u64*. + +#### `define `[`MSB6D`](#group__group__sam0__utils_1gacb8062d046ca06f5c28c9a015997494b) {#group__group__sam0__utils_1gacb8062d046ca06f5c28c9a015997494b} + +Most significant byte of 7th rank of *u64*. + +#### `define `[`MSB7D`](#group__group__sam0__utils_1ga0cbce69964fa2dd7bf05911d0b99b014) {#group__group__sam0__utils_1ga0cbce69964fa2dd7bf05911d0b99b014} + +Most significant byte of 8th rank of *u64*. + +#### `define `[`LSB7D`](#group__group__sam0__utils_1ga79fb849e13082fdd4adb02debbad7f1a) {#group__group__sam0__utils_1ga79fb849e13082fdd4adb02debbad7f1a} + +Least significant byte of 8th rank of *u64*. + +#### `define `[`LSB6D`](#group__group__sam0__utils_1gab90afefaf3b5cb2507ab3c496d8f643c) {#group__group__sam0__utils_1gab90afefaf3b5cb2507ab3c496d8f643c} + +Least significant byte of 7th rank of *u64*. + +#### `define `[`LSB5D`](#group__group__sam0__utils_1gac379acb246797736332fa1b8ae481b34) {#group__group__sam0__utils_1gac379acb246797736332fa1b8ae481b34} + +Least significant byte of 6th rank of *u64*. + +#### `define `[`LSB4D`](#group__group__sam0__utils_1gaab745f30b9b841f9ccd9ace0a5a1a9e5) {#group__group__sam0__utils_1gaab745f30b9b841f9ccd9ace0a5a1a9e5} + +Least significant byte of 5th rank of *u64*. + +#### `define `[`LSB3D`](#group__group__sam0__utils_1ga99213c01b979c347950eba4277f0499a) {#group__group__sam0__utils_1ga99213c01b979c347950eba4277f0499a} + +Least significant byte of 4th rank of *u64*. + +#### `define `[`LSB2D`](#group__group__sam0__utils_1gaba3bea07dcc4a37039b7effd4da03b9e) {#group__group__sam0__utils_1gaba3bea07dcc4a37039b7effd4da03b9e} + +Least significant byte of 3rd rank of *u64*. + +#### `define `[`LSB1D`](#group__group__sam0__utils_1ga42179f159b798116eb615102a549aa85) {#group__group__sam0__utils_1ga42179f159b798116eb615102a549aa85} + +Least significant byte of 2nd rank of *u64*. + +#### `define `[`LSB0D`](#group__group__sam0__utils_1ga2e20f5ef87ccf0ad44c1d49d6ffd80a3) {#group__group__sam0__utils_1ga2e20f5ef87ccf0ad44c1d49d6ffd80a3} + +Least significant byte of 1st rank of *u64*. + +#### `define `[`LSB0`](#group__group__sam0__utils_1ga844ec34df36feb927dc92007af14674a) {#group__group__sam0__utils_1ga844ec34df36feb927dc92007af14674a} + +Least significant byte of 1st rank of *u32*. + +#### `define `[`LSB1`](#group__group__sam0__utils_1ga2d1e45154b07481f0579ecc725e4edff) {#group__group__sam0__utils_1ga2d1e45154b07481f0579ecc725e4edff} + +Least significant byte of 2nd rank of *u32*. + +#### `define `[`LSB2`](#group__group__sam0__utils_1ga8967f5ae0174b01ce44c502ebd14035a) {#group__group__sam0__utils_1ga8967f5ae0174b01ce44c502ebd14035a} + +Least significant byte of 3rd rank of *u32*. + +#### `define `[`LSB3`](#group__group__sam0__utils_1ga5d9ff393e7c8764112a1167db19b16b1) {#group__group__sam0__utils_1ga5d9ff393e7c8764112a1167db19b16b1} + +Least significant byte of 4th rank of *u32*. + +#### `define `[`MSB3`](#group__group__sam0__utils_1gaeeb8918fc580ce01d45f71863eebff90) {#group__group__sam0__utils_1gaeeb8918fc580ce01d45f71863eebff90} + +Most significant byte of 4th rank of *u32*. + +#### `define `[`MSB2`](#group__group__sam0__utils_1ga8683254be29bcfe3cf2fa646890d3942) {#group__group__sam0__utils_1ga8683254be29bcfe3cf2fa646890d3942} + +Most significant byte of 3rd rank of *u32*. + +#### `define `[`MSB1`](#group__group__sam0__utils_1ga3facab9f8ebf70ad6e16038465e2bedc) {#group__group__sam0__utils_1ga3facab9f8ebf70ad6e16038465e2bedc} + +Most significant byte of 2nd rank of *u32*. + +#### `define `[`MSB0`](#group__group__sam0__utils_1gafb81783b8186acd7182a971048b0c6b3) {#group__group__sam0__utils_1gafb81783b8186acd7182a971048b0c6b3} + +Most significant byte of 1st rank of *u32*. + +#### `define `[`FLASH_DECLARE`](#group__group__sam0__utils_1ga9b84ecc6b34a71f797ceb8b8f7b8d384) {#group__group__sam0__utils_1ga9b84ecc6b34a71f797ceb8b8f7b8d384} + +#### `define `[`FLASH_EXTERN`](#group__group__sam0__utils_1gaaef0fd990bb5bd9cdf11334f7c689fd7) {#group__group__sam0__utils_1gaaef0fd990bb5bd9cdf11334f7c689fd7} + +#### `define `[`PGM_READ_BYTE`](#group__group__sam0__utils_1gafe9b83c73d4840986478ec67d3eb7718) {#group__group__sam0__utils_1gafe9b83c73d4840986478ec67d3eb7718} + +#### `define `[`PGM_READ_WORD`](#group__group__sam0__utils_1ga92576bffe51090dcb6d5c67e07b9eec7) {#group__group__sam0__utils_1ga92576bffe51090dcb6d5c67e07b9eec7} + +#### `define `[`MEMCPY_ENDIAN`](#group__group__sam0__utils_1ga85a7d71a016789b1766f9b27d0530347) {#group__group__sam0__utils_1ga85a7d71a016789b1766f9b27d0530347} + +#### `define `[`PGM_READ_BLOCK`](#group__group__sam0__utils_1ga8900e4615b7d7143a6c38e2a39087538) {#group__group__sam0__utils_1ga8900e4615b7d7143a6c38e2a39087538} + +#### `define `[`CMD_ID_OCTET`](#group__group__sam0__utils_1gabf2b95fa77301377cdcf79eb615551db) {#group__group__sam0__utils_1gabf2b95fa77301377cdcf79eb615551db} + +#### `define `[`CPU_ENDIAN_TO_LE16`](#group__group__sam0__utils_1ga7c15ca0f3159182efc4b80a00768c2c0) {#group__group__sam0__utils_1ga7c15ca0f3159182efc4b80a00768c2c0} + +#### `define `[`CPU_ENDIAN_TO_LE32`](#group__group__sam0__utils_1gaa2fd4bfb7af44220ce4205e2aa371017) {#group__group__sam0__utils_1gaa2fd4bfb7af44220ce4205e2aa371017} + +#### `define `[`CPU_ENDIAN_TO_LE64`](#group__group__sam0__utils_1ga6f1e86f452c8f327f9ca96cbf6a65c81) {#group__group__sam0__utils_1ga6f1e86f452c8f327f9ca96cbf6a65c81} + +#### `define `[`LE16_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gaceb02fdef243c22d2559e260185fb579) {#group__group__sam0__utils_1gaceb02fdef243c22d2559e260185fb579} + +#### `define `[`LE32_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga2df63369ef525ba98832132ce5a43346) {#group__group__sam0__utils_1ga2df63369ef525ba98832132ce5a43346} + +#### `define `[`LE64_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gab675071ce5a4644b205cdbc858417ccd) {#group__group__sam0__utils_1gab675071ce5a4644b205cdbc858417ccd} + +#### `define `[`CLE16_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga4ac6e032d1ce0ae6d2e460da93ce8732) {#group__group__sam0__utils_1ga4ac6e032d1ce0ae6d2e460da93ce8732} + +#### `define `[`CLE32_TO_CPU_ENDIAN`](#group__group__sam0__utils_1ga3ff07a7496222efe8bc7d7b7b0342b0d) {#group__group__sam0__utils_1ga3ff07a7496222efe8bc7d7b7b0342b0d} + +#### `define `[`CLE64_TO_CPU_ENDIAN`](#group__group__sam0__utils_1gacbbba93256e2d892c748d56a42f00f9b) {#group__group__sam0__utils_1gacbbba93256e2d892c748d56a42f00f9b} + +#### `define `[`CCPU_ENDIAN_TO_LE16`](#group__group__sam0__utils_1ga5fd2d3ed2fc9234277b659b67d33bc64) {#group__group__sam0__utils_1ga5fd2d3ed2fc9234277b659b67d33bc64} + +#### `define `[`CCPU_ENDIAN_TO_LE32`](#group__group__sam0__utils_1ga1e3290451e5c7b98175911c9219b5123) {#group__group__sam0__utils_1ga1e3290451e5c7b98175911c9219b5123} + +#### `define `[`CCPU_ENDIAN_TO_LE64`](#group__group__sam0__utils_1ga00483bf27ea1e8a2143c6baf22b31f16) {#group__group__sam0__utils_1ga00483bf27ea1e8a2143c6baf22b31f16} + +#### `define `[`ADDR_COPY_DST_SRC_16`](#group__group__sam0__utils_1gac4609178e5c825e815f44fa123dcaaf7) {#group__group__sam0__utils_1gac4609178e5c825e815f44fa123dcaaf7} + +#### `define `[`ADDR_COPY_DST_SRC_64`](#group__group__sam0__utils_1ga0454afa80924c2183c8c672c043440cc) {#group__group__sam0__utils_1ga0454afa80924c2183c8c672c043440cc} + +#### `public inline static void `[`convert_64_bit_to_byte_array`](#group__group__sam0__utils_1gadca7cebb159c7ed180d3d07cccb74245)`(uint64_t value,uint8_t * data)` {#group__group__sam0__utils_1gadca7cebb159c7ed180d3d07cccb74245} + +Converts a 64-Bit value into a 8 Byte array. + +#### Parameters +* `value` 64-Bit value + +* `data` Pointer to the 8 Byte array to be updated with 64-Bit value + +#### `public inline static void `[`convert_16_bit_to_byte_array`](#group__group__sam0__utils_1ga2de8d131d6afca8b368486f56c911e75)`(uint16_t value,uint8_t * data)` {#group__group__sam0__utils_1ga2de8d131d6afca8b368486f56c911e75} + +Converts a 16-Bit value into a 2 Byte array. + +#### Parameters +* `value` 16-Bit value + +* `data` Pointer to the 2 Byte array to be updated with 16-Bit value + +#### `public inline static void `[`convert_spec_16_bit_to_byte_array`](#group__group__sam0__utils_1gaa9724d81bfe44a06b0372d144cd98e36)`(uint16_t value,uint8_t * data)` {#group__group__sam0__utils_1gaa9724d81bfe44a06b0372d144cd98e36} + +#### `public inline static void `[`convert_16_bit_to_byte_address`](#group__group__sam0__utils_1ga9634f2d7292e1209fe3b83254a66c450)`(uint16_t value,uint8_t * data)` {#group__group__sam0__utils_1ga9634f2d7292e1209fe3b83254a66c450} + +#### `public inline static uint16_t `[`convert_byte_array_to_16_bit`](#group__group__sam0__utils_1gad3726f56d0820acc7bae83993bd8897c)`(uint8_t * data)` {#group__group__sam0__utils_1gad3726f56d0820acc7bae83993bd8897c} + +#### `public inline static uint32_t `[`convert_byte_array_to_32_bit`](#group__group__sam0__utils_1ga6e01ed4a4718b439d295b5124ede09e3)`(uint8_t * data)` {#group__group__sam0__utils_1ga6e01ed4a4718b439d295b5124ede09e3} + +#### `public inline static uint64_t `[`convert_byte_array_to_64_bit`](#group__group__sam0__utils_1ga45ffdbdc2d7a6d1dbf91b2fe8d880347)`(uint8_t * data)` {#group__group__sam0__utils_1ga45ffdbdc2d7a6d1dbf91b2fe8d880347} + +Converts a 8 Byte array into a 64-Bit value. + +#### Parameters +* `data` Specifies the pointer to the 8 Byte array + +#### Returns +64-Bit value + +# struct `StructPtr` {#struct_struct_ptr} + +Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public int64_t * `[`s64ptr`](#struct_struct_ptr_1ab436f27258753b9cf149312d1e668d7e) | +`public uint64_t * `[`u64ptr`](#struct_struct_ptr_1a01a7db75ae97caa7457038b8ee801d1f) | +`public int32_t * `[`s32ptr`](#struct_struct_ptr_1a106ea0461fc89cf4c58cec908c448aef) | +`public uint32_t * `[`u32ptr`](#struct_struct_ptr_1a00500224ac165192ac888251a076606d) | +`public int16_t * `[`s16ptr`](#struct_struct_ptr_1a55c23b18ff2cf478679ca49da3927345) | +`public uint16_t * `[`u16ptr`](#struct_struct_ptr_1a15c8362aa58f36ae5de7f6180550d6b5) | +`public int8_t * `[`s8ptr`](#struct_struct_ptr_1a874b2108143ffd4d2a83baa5d8fa8cad) | +`public uint8_t * `[`u8ptr`](#struct_struct_ptr_1acc04e057a962c975bbdf62664c52ff2c) | + +## Members + +#### `public int64_t * `[`s64ptr`](#struct_struct_ptr_1ab436f27258753b9cf149312d1e668d7e) {#struct_struct_ptr_1ab436f27258753b9cf149312d1e668d7e} + +#### `public uint64_t * `[`u64ptr`](#struct_struct_ptr_1a01a7db75ae97caa7457038b8ee801d1f) {#struct_struct_ptr_1a01a7db75ae97caa7457038b8ee801d1f} + +#### `public int32_t * `[`s32ptr`](#struct_struct_ptr_1a106ea0461fc89cf4c58cec908c448aef) {#struct_struct_ptr_1a106ea0461fc89cf4c58cec908c448aef} + +#### `public uint32_t * `[`u32ptr`](#struct_struct_ptr_1a00500224ac165192ac888251a076606d) {#struct_struct_ptr_1a00500224ac165192ac888251a076606d} + +#### `public int16_t * `[`s16ptr`](#struct_struct_ptr_1a55c23b18ff2cf478679ca49da3927345) {#struct_struct_ptr_1a55c23b18ff2cf478679ca49da3927345} + +#### `public uint16_t * `[`u16ptr`](#struct_struct_ptr_1a15c8362aa58f36ae5de7f6180550d6b5) {#struct_struct_ptr_1a15c8362aa58f36ae5de7f6180550d6b5} + +#### `public int8_t * `[`s8ptr`](#struct_struct_ptr_1a874b2108143ffd4d2a83baa5d8fa8cad) {#struct_struct_ptr_1a874b2108143ffd4d2a83baa5d8fa8cad} + +#### `public uint8_t * `[`u8ptr`](#struct_struct_ptr_1acc04e057a962c975bbdf62664c52ff2c) {#struct_struct_ptr_1acc04e057a962c975bbdf62664c52ff2c} + +# struct `StructVPtr` {#struct_struct_v_ptr} + +Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public int64_t * `[`s64ptr`](#struct_struct_v_ptr_1a2908c8cb1c7d816d7f9d3a30531818f8) | +`public uint64_t * `[`u64ptr`](#struct_struct_v_ptr_1a1acc0e7be6320444fc9a35fbd89f1f37) | +`public int32_t * `[`s32ptr`](#struct_struct_v_ptr_1ac419cbdd704de7024e989caaf9e19a98) | +`public uint32_t * `[`u32ptr`](#struct_struct_v_ptr_1abdec22b9984813fac831e57d45cae742) | +`public int16_t * `[`s16ptr`](#struct_struct_v_ptr_1aee6c3ba77b4b25f556abb8a41053caf4) | +`public uint16_t * `[`u16ptr`](#struct_struct_v_ptr_1ae008948f89e2a5ee3102016f82023b42) | +`public int8_t * `[`s8ptr`](#struct_struct_v_ptr_1ab07ceff1caf6f3bb01bd31296a36daf9) | +`public uint8_t * `[`u8ptr`](#struct_struct_v_ptr_1a4213589251839cd1f42c3343c6cb9be9) | + +## Members + +#### `public int64_t * `[`s64ptr`](#struct_struct_v_ptr_1a2908c8cb1c7d816d7f9d3a30531818f8) {#struct_struct_v_ptr_1a2908c8cb1c7d816d7f9d3a30531818f8} + +#### `public uint64_t * `[`u64ptr`](#struct_struct_v_ptr_1a1acc0e7be6320444fc9a35fbd89f1f37) {#struct_struct_v_ptr_1a1acc0e7be6320444fc9a35fbd89f1f37} + +#### `public int32_t * `[`s32ptr`](#struct_struct_v_ptr_1ac419cbdd704de7024e989caaf9e19a98) {#struct_struct_v_ptr_1ac419cbdd704de7024e989caaf9e19a98} + +#### `public uint32_t * `[`u32ptr`](#struct_struct_v_ptr_1abdec22b9984813fac831e57d45cae742) {#struct_struct_v_ptr_1abdec22b9984813fac831e57d45cae742} + +#### `public int16_t * `[`s16ptr`](#struct_struct_v_ptr_1aee6c3ba77b4b25f556abb8a41053caf4) {#struct_struct_v_ptr_1aee6c3ba77b4b25f556abb8a41053caf4} + +#### `public uint16_t * `[`u16ptr`](#struct_struct_v_ptr_1ae008948f89e2a5ee3102016f82023b42) {#struct_struct_v_ptr_1ae008948f89e2a5ee3102016f82023b42} + +#### `public int8_t * `[`s8ptr`](#struct_struct_v_ptr_1ab07ceff1caf6f3bb01bd31296a36daf9) {#struct_struct_v_ptr_1ab07ceff1caf6f3bb01bd31296a36daf9} + +#### `public uint8_t * `[`u8ptr`](#struct_struct_v_ptr_1a4213589251839cd1f42c3343c6cb9be9) {#struct_struct_v_ptr_1a4213589251839cd1f42c3343c6cb9be9} + +# struct `StructCPtr` {#struct_struct_c_ptr} + +Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public const int64_t * `[`s64ptr`](#struct_struct_c_ptr_1ac9ea294aaa07e5a63204530ebf3dd3d2) | +`public const uint64_t * `[`u64ptr`](#struct_struct_c_ptr_1abbc67642e882a52be564515f1c8f12cb) | +`public const int32_t * `[`s32ptr`](#struct_struct_c_ptr_1af6182ebecd1280fa1714762f2d81d5d3) | +`public const uint32_t * `[`u32ptr`](#struct_struct_c_ptr_1a12f0da0bcf30aca9703630565d8be204) | +`public const int16_t * `[`s16ptr`](#struct_struct_c_ptr_1a153aa1a4a18fe39a05be056a372d19c9) | +`public const uint16_t * `[`u16ptr`](#struct_struct_c_ptr_1a4ff05b3b8a78949bf0036fe340b98b05) | +`public const int8_t * `[`s8ptr`](#struct_struct_c_ptr_1a2e21f1ae56dd4da3f534ccebfa234fcc) | +`public const uint8_t * `[`u8ptr`](#struct_struct_c_ptr_1acb08e5689c70ca4ef5e0d984f15f47ae) | + +## Members + +#### `public const int64_t * `[`s64ptr`](#struct_struct_c_ptr_1ac9ea294aaa07e5a63204530ebf3dd3d2) {#struct_struct_c_ptr_1ac9ea294aaa07e5a63204530ebf3dd3d2} + +#### `public const uint64_t * `[`u64ptr`](#struct_struct_c_ptr_1abbc67642e882a52be564515f1c8f12cb) {#struct_struct_c_ptr_1abbc67642e882a52be564515f1c8f12cb} + +#### `public const int32_t * `[`s32ptr`](#struct_struct_c_ptr_1af6182ebecd1280fa1714762f2d81d5d3) {#struct_struct_c_ptr_1af6182ebecd1280fa1714762f2d81d5d3} + +#### `public const uint32_t * `[`u32ptr`](#struct_struct_c_ptr_1a12f0da0bcf30aca9703630565d8be204) {#struct_struct_c_ptr_1a12f0da0bcf30aca9703630565d8be204} + +#### `public const int16_t * `[`s16ptr`](#struct_struct_c_ptr_1a153aa1a4a18fe39a05be056a372d19c9) {#struct_struct_c_ptr_1a153aa1a4a18fe39a05be056a372d19c9} + +#### `public const uint16_t * `[`u16ptr`](#struct_struct_c_ptr_1a4ff05b3b8a78949bf0036fe340b98b05) {#struct_struct_c_ptr_1a4ff05b3b8a78949bf0036fe340b98b05} + +#### `public const int8_t * `[`s8ptr`](#struct_struct_c_ptr_1a2e21f1ae56dd4da3f534ccebfa234fcc) {#struct_struct_c_ptr_1a2e21f1ae56dd4da3f534ccebfa234fcc} + +#### `public const uint8_t * `[`u8ptr`](#struct_struct_c_ptr_1acb08e5689c70ca4ef5e0d984f15f47ae) {#struct_struct_c_ptr_1acb08e5689c70ca4ef5e0d984f15f47ae} + +# struct `StructCVPtr` {#struct_struct_c_v_ptr} + +Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public const volatile int64_t * `[`s64ptr`](#struct_struct_c_v_ptr_1aa79f3b96a6ad079e73cc0be13bd0e765) | +`public const volatile uint64_t * `[`u64ptr`](#struct_struct_c_v_ptr_1a24a2bedaf12d427819c62babba34e2ef) | +`public const volatile int32_t * `[`s32ptr`](#struct_struct_c_v_ptr_1a0aa7d6575057bad6b799c9b2909c077b) | +`public const volatile uint32_t * `[`u32ptr`](#struct_struct_c_v_ptr_1a0e4e80d3c57067ad85c71af39d0ea817) | +`public const volatile int16_t * `[`s16ptr`](#struct_struct_c_v_ptr_1a97b5d4643b545ecc9ac9c68fa35b74fe) | +`public const volatile uint16_t * `[`u16ptr`](#struct_struct_c_v_ptr_1a288ff13c7abb2360d62009e2711e7485) | +`public const volatile int8_t * `[`s8ptr`](#struct_struct_c_v_ptr_1afc839213e22402ccf98e7d143453b58d) | +`public const volatile uint8_t * `[`u8ptr`](#struct_struct_c_v_ptr_1ae6228fb5d646745079910ea045f314e3) | + +## Members + +#### `public const volatile int64_t * `[`s64ptr`](#struct_struct_c_v_ptr_1aa79f3b96a6ad079e73cc0be13bd0e765) {#struct_struct_c_v_ptr_1aa79f3b96a6ad079e73cc0be13bd0e765} + +#### `public const volatile uint64_t * `[`u64ptr`](#struct_struct_c_v_ptr_1a24a2bedaf12d427819c62babba34e2ef) {#struct_struct_c_v_ptr_1a24a2bedaf12d427819c62babba34e2ef} + +#### `public const volatile int32_t * `[`s32ptr`](#struct_struct_c_v_ptr_1a0aa7d6575057bad6b799c9b2909c077b) {#struct_struct_c_v_ptr_1a0aa7d6575057bad6b799c9b2909c077b} + +#### `public const volatile uint32_t * `[`u32ptr`](#struct_struct_c_v_ptr_1a0e4e80d3c57067ad85c71af39d0ea817) {#struct_struct_c_v_ptr_1a0e4e80d3c57067ad85c71af39d0ea817} + +#### `public const volatile int16_t * `[`s16ptr`](#struct_struct_c_v_ptr_1a97b5d4643b545ecc9ac9c68fa35b74fe) {#struct_struct_c_v_ptr_1a97b5d4643b545ecc9ac9c68fa35b74fe} + +#### `public const volatile uint16_t * `[`u16ptr`](#struct_struct_c_v_ptr_1a288ff13c7abb2360d62009e2711e7485) {#struct_struct_c_v_ptr_1a288ff13c7abb2360d62009e2711e7485} + +#### `public const volatile int8_t * `[`s8ptr`](#struct_struct_c_v_ptr_1afc839213e22402ccf98e7d143453b58d) {#struct_struct_c_v_ptr_1afc839213e22402ccf98e7d143453b58d} + +#### `public const volatile uint8_t * `[`u8ptr`](#struct_struct_c_v_ptr_1ae6228fb5d646745079910ea045f314e3) {#struct_struct_c_v_ptr_1ae6228fb5d646745079910ea045f314e3} + diff --git a/internals_group_sam0_utils_status_codes.md b/internals_group_sam0_utils_status_codes.md new file mode 100644 index 00000000000..6e8d39a61ff --- /dev/null +++ b/internals_group_sam0_utils_status_codes.md @@ -0,0 +1,92 @@ +# group `group_sam0_utils_status_codes` {#group__group__sam0__utils__status__codes} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`STATUS_CATEGORY_MASK`](#group__group__sam0__utils__status__codes_1ga5bf938a904077896054cd093bf7d8fa8) | Mask to retrieve the error category of a status code. +`define `[`STATUS_ERROR_MASK`](#group__group__sam0__utils__status__codes_1ga4c46d8f176ca46ab775db0fe270d2f98) | Mask to retrieve the error code within the category of a status code. +`enum `[`status_categories`](#group__group__sam0__utils__status__codes_1ga477539e8a67b0cab096e8ecda6f5d7d6) | Status code error categories. +`enum `[`status_code`](#group__group__sam0__utils__status__codes_1ga751c892e5a46b8e7d282085a5a5bf151) | Status code that may be returned by shell commands and protocol implementations. +`enum `[`status_code_wireless`](#group__group__sam0__utils__status__codes_1ga29235ed38b6f02861f29daae665ac3a2) | Status codes used by MAC stack. + +## Members + +#### `define `[`STATUS_CATEGORY_MASK`](#group__group__sam0__utils__status__codes_1ga5bf938a904077896054cd093bf7d8fa8) {#group__group__sam0__utils__status__codes_1ga5bf938a904077896054cd093bf7d8fa8} + +Mask to retrieve the error category of a status code. + +#### `define `[`STATUS_ERROR_MASK`](#group__group__sam0__utils__status__codes_1ga4c46d8f176ca46ab775db0fe270d2f98) {#group__group__sam0__utils__status__codes_1ga4c46d8f176ca46ab775db0fe270d2f98} + +Mask to retrieve the error code within the category of a status code. + +#### `enum `[`status_categories`](#group__group__sam0__utils__status__codes_1ga477539e8a67b0cab096e8ecda6f5d7d6) {#group__group__sam0__utils__status__codes_1ga477539e8a67b0cab096e8ecda6f5d7d6} + + Values | Descriptions +--------------------------------|--------------------------------------------- +STATUS_CATEGORY_OK | +STATUS_CATEGORY_COMMON | +STATUS_CATEGORY_ANALOG | +STATUS_CATEGORY_COM | +STATUS_CATEGORY_IO | + +Status code error categories. + +#### `enum `[`status_code`](#group__group__sam0__utils__status__codes_1ga751c892e5a46b8e7d282085a5a5bf151) {#group__group__sam0__utils__status__codes_1ga751c892e5a46b8e7d282085a5a5bf151} + + Values | Descriptions +--------------------------------|--------------------------------------------- +STATUS_OK | +STATUS_VALID_DATA | +STATUS_NO_CHANGE | +STATUS_ABORTED | +STATUS_BUSY | +STATUS_SUSPEND | +STATUS_ERR_IO | +STATUS_ERR_REQ_FLUSHED | +STATUS_ERR_TIMEOUT | +STATUS_ERR_BAD_DATA | +STATUS_ERR_NOT_FOUND | +STATUS_ERR_UNSUPPORTED_DEV | +STATUS_ERR_NO_MEMORY | +STATUS_ERR_INVALID_ARG | +STATUS_ERR_BAD_ADDRESS | +STATUS_ERR_BAD_FORMAT | +STATUS_ERR_BAD_FRQ | +STATUS_ERR_DENIED | +STATUS_ERR_ALREADY_INITIALIZED | +STATUS_ERR_OVERFLOW | +STATUS_ERR_NOT_INITIALIZED | +STATUS_ERR_SAMPLERATE_UNAVAILABLE | +STATUS_ERR_RESOLUTION_UNAVAILABLE | +STATUS_ERR_BAUDRATE_UNAVAILABLE | +STATUS_ERR_PACKET_COLLISION | +STATUS_ERR_PROTOCOL | +STATUS_ERR_PIN_MUX_INVALID | + +Status code that may be returned by shell commands and protocol implementations. + +Any change to these status codes and the corresponding message strings is strictly forbidden. New codes can be added, however, but make sure that any message string tables are updated at the same time. + +#### `enum `[`status_code_wireless`](#group__group__sam0__utils__status__codes_1ga29235ed38b6f02861f29daae665ac3a2) {#group__group__sam0__utils__status__codes_1ga29235ed38b6f02861f29daae665ac3a2} + + Values | Descriptions +--------------------------------|--------------------------------------------- +ERR_IO_ERROR | I/O error. +ERR_FLUSHED | Request flushed from queue. +ERR_TIMEOUT | Operation timed out. +ERR_BAD_DATA | Data integrity check failed. +ERR_PROTOCOL | Protocol error. +ERR_UNSUPPORTED_DEV | Unsupported device. +ERR_NO_MEMORY | Insufficient memory. +ERR_INVALID_ARG | Invalid argument. +ERR_BAD_ADDRESS | Bad address. +ERR_BUSY | Resource is busy. +ERR_BAD_FORMAT | Data format not recognized. +ERR_NO_TIMER | No timer available. +ERR_TIMER_ALREADY_RUNNING | Timer already running. +ERR_TIMER_NOT_RUNNING | Timer not running. +OPERATION_IN_PROGRESS | Operation in progress. + +Status codes used by MAC stack. + diff --git a/internals_input_callback_reg.md b/internals_input_callback_reg.md new file mode 100644 index 00000000000..60b837624b1 --- /dev/null +++ b/internals_input_callback_reg.md @@ -0,0 +1,169 @@ +# group `input_callback_reg` {#group__input__callback__reg} + +These are the functions you use to register your input callbacks. + +The functions are called when the appropriate midi message is matched on the associated device's input. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a control change message (cc) callback. +`public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a note on callback. +`public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a note off callback. +`public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register an after touch callback. +`public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a pitch bend callback. +`public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a song position callback. +`public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a program change callback. +`public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a channel pressure callback. +`public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a song select callback. +`public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a tc quarter frame callback. +`public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_one_byte_func_t func)` | Register a realtime callback. +`public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_one_byte_func_t func)` | Register a tune request callback. +`public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_sysex_func_t func)` | Register a sysex callback. +`public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t func)` | Register fall through callback. +`public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t func)` | Register a catch all callback. + +## Members + +#### `public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718} + +Register a control change message (cc) callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga3962f276c17618923f1152779552103e} + +Register a note on callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d} + +Register a note off callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f} + +Register an after touch callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48} + +Register a pitch bend callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6} + +Register a song position callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127} + +Register a program change callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5} + +Register a channel pressure callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72} + +Register a song select callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e} + +Register a tc quarter frame callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a} + +Register a realtime callback. + +The callback will be called for all of the real time message types. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1} + +Register a tune request callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_sysex_func_t func)` {#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48} + +Register a sysex callback. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94} + +Register fall through callback. + +This is only called if a more specific callback is not matched and called. For instance, if you don't register a note on callback but you get a note on message the fall through callback will be called, if it is registered. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + +#### `public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99} + +Register a catch all callback. + +If registered, the catch all callback is called for every message that is matched, even if a more specific or the fallthrough callback is registered. + +#### Parameters +* `device` the device associate with + +* `func` the callback function to register + diff --git a/internals_midi_device.md b/internals_midi_device.md new file mode 100644 index 00000000000..a812f0ff188 --- /dev/null +++ b/internals_midi_device.md @@ -0,0 +1,143 @@ +# group `midi_device` {#group__midi__device} + +You use the functions when you are implementing your own midi device. + +You set a send function to actually send bytes via your device, this method is called when you call a send function with this device, for instance midi_send_cc + +You use the midi_device_input to process input data from the device and pass it through the device's associated callbacks. + +You use the midi_device_set_pre_input_process_func if you want to have a function called at the beginning of the device's process function, generally to poll for input and pass that into midi_device_input + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`MIDI_INPUT_QUEUE_LENGTH`](#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8) | +`enum `[`input_state_t`](#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621) | +`public void `[`midi_device_input`](#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t cnt,uint8_t * input)` | Process input bytes. This function parses bytes and calls the appropriate callbacks associated with the given device. You use this function if you are creating a custom device and you want to have midi input. +`public void `[`midi_device_set_send_func`](#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t send_func)` | Set the callback function that will be used for sending output data bytes. This is only used if you're creating a custom device. You'll most likely want the callback function to disable interrupts so that you can call the various midi send functions without worrying about locking. +`public void `[`midi_device_set_pre_input_process_func`](#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_no_byte_func_t pre_process_func)` | Set a callback which is called at the beginning of the midi_device_process call. This can be used to poll for input data and send the data through the midi_device_input function. You'll probably only use this if you're creating a custom device. +`struct `[`_midi_device`](#struct__midi__device) | This structure represents the input and output functions and processing data for a midi device. + +## Members + +#### `define `[`MIDI_INPUT_QUEUE_LENGTH`](#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8) {#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8} + +#### `enum `[`input_state_t`](#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621) {#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621} + + Values | Descriptions +--------------------------------|--------------------------------------------- +IDLE | +ONE_BYTE_MESSAGE | +TWO_BYTE_MESSAGE | +THREE_BYTE_MESSAGE | +SYSEX_MESSAGE | + +#### `public void `[`midi_device_input`](#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t cnt,uint8_t * input)` {#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db} + +Process input bytes. This function parses bytes and calls the appropriate callbacks associated with the given device. You use this function if you are creating a custom device and you want to have midi input. + +#### Parameters +* `device` the midi device to associate the input with + +* `cnt` the number of bytes you are processing + +* `input` the bytes to process + +#### `public void `[`midi_device_set_send_func`](#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_var_byte_func_t send_func)` {#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673} + +Set the callback function that will be used for sending output data bytes. This is only used if you're creating a custom device. You'll most likely want the callback function to disable interrupts so that you can call the various midi send functions without worrying about locking. + +#### Parameters +* `device` the midi device to associate this callback with + +* `send_func` the callback function that will do the sending + +#### `public void `[`midi_device_set_pre_input_process_func`](#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,midi_no_byte_func_t pre_process_func)` {#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69} + +Set a callback which is called at the beginning of the midi_device_process call. This can be used to poll for input data and send the data through the midi_device_input function. You'll probably only use this if you're creating a custom device. + +#### Parameters +* `device` the midi device to associate this callback with + +* `midi_no_byte_func_t` the actual callback function + +# struct `_midi_device` {#struct__midi__device} + +This structure represents the input and output functions and processing data for a midi device. + +A device can represent an actual physical device [serial port, usb port] or something virtual. You should not need to modify this structure directly. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public midi_var_byte_func_t `[`send_func`](#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9) | +`public midi_three_byte_func_t `[`input_cc_callback`](#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1) | +`public midi_three_byte_func_t `[`input_noteon_callback`](#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c) | +`public midi_three_byte_func_t `[`input_noteoff_callback`](#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84) | +`public midi_three_byte_func_t `[`input_aftertouch_callback`](#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f) | +`public midi_three_byte_func_t `[`input_pitchbend_callback`](#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18) | +`public midi_three_byte_func_t `[`input_songposition_callback`](#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586) | +`public midi_two_byte_func_t `[`input_progchange_callback`](#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da) | +`public midi_two_byte_func_t `[`input_chanpressure_callback`](#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7) | +`public midi_two_byte_func_t `[`input_songselect_callback`](#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f) | +`public midi_two_byte_func_t `[`input_tc_quarterframe_callback`](#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0) | +`public midi_one_byte_func_t `[`input_realtime_callback`](#struct__midi__device_1a9448eba4afb7e43650434748db3777be) | +`public midi_one_byte_func_t `[`input_tunerequest_callback`](#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d) | +`public midi_sysex_func_t `[`input_sysex_callback`](#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2) | +`public midi_var_byte_func_t `[`input_fallthrough_callback`](#struct__midi__device_1abb974ec6d734001b4a0e370f292be503) | +`public midi_var_byte_func_t `[`input_catchall_callback`](#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8) | +`public midi_no_byte_func_t `[`pre_input_process_callback`](#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754) | +`public uint8_t `[`input_buffer`](#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a) | +`public input_state_t `[`input_state`](#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39) | +`public uint16_t `[`input_count`](#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d) | +`public uint8_t `[`input_queue_data`](#struct__midi__device_1ada41de021135dc423abedcbb30f366ff) | +`public `[`byteQueue_t`](.build/docs/internals_undefined.md#structbyte_queue__t)` `[`input_queue`](#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f) | + +## Members + +#### `public midi_var_byte_func_t `[`send_func`](#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9) {#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9} + +#### `public midi_three_byte_func_t `[`input_cc_callback`](#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1) {#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1} + +#### `public midi_three_byte_func_t `[`input_noteon_callback`](#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c) {#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c} + +#### `public midi_three_byte_func_t `[`input_noteoff_callback`](#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84) {#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84} + +#### `public midi_three_byte_func_t `[`input_aftertouch_callback`](#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f) {#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f} + +#### `public midi_three_byte_func_t `[`input_pitchbend_callback`](#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18) {#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18} + +#### `public midi_three_byte_func_t `[`input_songposition_callback`](#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586) {#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586} + +#### `public midi_two_byte_func_t `[`input_progchange_callback`](#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da) {#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da} + +#### `public midi_two_byte_func_t `[`input_chanpressure_callback`](#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7) {#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7} + +#### `public midi_two_byte_func_t `[`input_songselect_callback`](#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f) {#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f} + +#### `public midi_two_byte_func_t `[`input_tc_quarterframe_callback`](#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0) {#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0} + +#### `public midi_one_byte_func_t `[`input_realtime_callback`](#struct__midi__device_1a9448eba4afb7e43650434748db3777be) {#struct__midi__device_1a9448eba4afb7e43650434748db3777be} + +#### `public midi_one_byte_func_t `[`input_tunerequest_callback`](#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d) {#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d} + +#### `public midi_sysex_func_t `[`input_sysex_callback`](#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2) {#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2} + +#### `public midi_var_byte_func_t `[`input_fallthrough_callback`](#struct__midi__device_1abb974ec6d734001b4a0e370f292be503) {#struct__midi__device_1abb974ec6d734001b4a0e370f292be503} + +#### `public midi_var_byte_func_t `[`input_catchall_callback`](#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8) {#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8} + +#### `public midi_no_byte_func_t `[`pre_input_process_callback`](#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754) {#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754} + +#### `public uint8_t `[`input_buffer`](#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a) {#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a} + +#### `public input_state_t `[`input_state`](#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39) {#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39} + +#### `public uint16_t `[`input_count`](#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d) {#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d} + +#### `public uint8_t `[`input_queue_data`](#struct__midi__device_1ada41de021135dc423abedcbb30f366ff) {#struct__midi__device_1ada41de021135dc423abedcbb30f366ff} + +#### `public `[`byteQueue_t`](.build/docs/internals_undefined.md#structbyte_queue__t)` `[`input_queue`](#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f) {#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f} + diff --git a/internals_midi_device_setup_process.md b/internals_midi_device_setup_process.md new file mode 100644 index 00000000000..9cab53fc0a6 --- /dev/null +++ b/internals_midi_device_setup_process.md @@ -0,0 +1,31 @@ +# group `midi_device_setup_process` {#group__midi__device__setup__process} + +These are method that you must use to initialize and run a device. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public void `[`midi_device_init`](#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Initialize a device. +`public void `[`midi_device_process`](#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Process input data. + +## Members + +#### `public void `[`midi_device_init`](#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9} + +Initialize a device. + +You must call this before using the device in question. + +#### Parameters +* `device` the device to initialize + +#### `public void `[`midi_device_process`](#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b} + +Process input data. + +This method drives the input processing, you must call this method frequently if you expect to have your input callbacks called. + +#### Parameters +* `device` the device to process + diff --git a/internals_midi_util.md b/internals_midi_util.md new file mode 100644 index 00000000000..eb02cb5b23c --- /dev/null +++ b/internals_midi_util.md @@ -0,0 +1,54 @@ +# group `midi_util` {#group__midi__util} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`enum `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e) | An enumeration of the possible packet length values. +`public bool `[`midi_is_statusbyte`](#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5)`(uint8_t theByte)` | Test to see if the byte given is a status byte. +`public bool `[`midi_is_realtime`](#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7)`(uint8_t theByte)` | Test to see if the byte given is a realtime message. +`public `[`midi_packet_length_t`](.build/docs/internals_undefined.md#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e)` `[`midi_packet_length`](#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175)`(uint8_t status)` | Find the length of the packet associated with the status byte given. + +## Members + +#### `enum `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e) {#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e} + + Values | Descriptions +--------------------------------|--------------------------------------------- +UNDEFINED | +ONE | +TWO | +THREE | + +An enumeration of the possible packet length values. + +#### `public bool `[`midi_is_statusbyte`](#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5)`(uint8_t theByte)` {#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5} + +Test to see if the byte given is a status byte. + +#### Parameters +* `theByte` the byte to test + +#### Returns +true if the byte given is a midi status byte + +#### `public bool `[`midi_is_realtime`](#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7)`(uint8_t theByte)` {#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7} + +Test to see if the byte given is a realtime message. + +#### Parameters +* `theByte` the byte to test + +#### Returns +true if it is a realtime message, false otherwise + +#### `public `[`midi_packet_length_t`](.build/docs/internals_undefined.md#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e)` `[`midi_packet_length`](#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175)`(uint8_t status)` {#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175} + +Find the length of the packet associated with the status byte given. + +#### Parameters +* `status` the status byte + +#### Returns +the length of the packet, will return UNDEFINED if the byte is not a status byte or if it is a sysex status byte + diff --git a/internals_pfleury_lcd.md b/internals_pfleury_lcd.md new file mode 100644 index 00000000000..3080ce7e1eb --- /dev/null +++ b/internals_pfleury_lcd.md @@ -0,0 +1,27 @@ +# group `pfleury_lcd` {#group__pfleury__lcd} + +Basic routines for interfacing a HD44780U-based character LCD display. + +```cpp +#include +``` + +LCD character displays can be found in many devices, like espresso machines, laser printers. The Hitachi HD44780 controller and its compatible controllers like Samsung KS0066U have become an industry standard for these types of displays. + +This library allows easy interfacing with a HD44780 compatible display and can be operated in memory mapped mode (LCD_IO_MODE defined as 0 in the include file lcd.h.) or in 4-bit IO port mode (LCD_IO_MODE defined as 1). 8-bit IO port mode is not supported. + +Memory mapped mode is compatible with old Kanda STK200 starter kit, but also supports generation of R/W signal through A8 address line. + +**See also**: The chapter [Interfacing a HD44780 Based LCD to an AVR]( http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html) on my home page, which shows example circuits how to connect an LCD to an AVR controller. + +Peter Fleury [pfleury@gmx.ch](mailto:pfleury@gmx.ch)[http://tinyurl.com/peterfleury](http://tinyurl.com/peterfleury) + +2.0 + +(C) 2015 Peter Fleury, GNU General Public License Version 3 + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_send_functions.md b/internals_send_functions.md new file mode 100644 index 00000000000..2a03893c683 --- /dev/null +++ b/internals_send_functions.md @@ -0,0 +1,241 @@ +# group `send_functions` {#group__send__functions} + +These are the functions you use to send midi data through a device. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public void `[`midi_send_cc`](#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t val)` | Send a control change message (cc) via the given device. +`public void `[`midi_send_noteon`](#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` | Send a note on message via the given device. +`public void `[`midi_send_noteoff`](#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` | Send a note off message via the given device. +`public void `[`midi_send_aftertouch`](#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t note_num,uint8_t amt)` | Send an after touch message via the given device. +`public void `[`midi_send_pitchbend`](#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,int16_t amt)` | Send a pitch bend message via the given device. +`public void `[`midi_send_programchange`](#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num)` | Send a program change message via the given device. +`public void `[`midi_send_channelpressure`](#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t amt)` | Send a channel pressure message via the given device. +`public void `[`midi_send_clock`](#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a clock message via the given device. +`public void `[`midi_send_tick`](#group__send__functions_1ga2b43c7d433d940c5b907595aac947972)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a tick message via the given device. +`public void `[`midi_send_start`](#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a start message via the given device. +`public void `[`midi_send_continue`](#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a continue message via the given device. +`public void `[`midi_send_stop`](#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a stop message via the given device. +`public void `[`midi_send_activesense`](#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send an active sense message via the given device. +`public void `[`midi_send_reset`](#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a reset message via the given device. +`public void `[`midi_send_tcquarterframe`](#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t time)` | Send a tc quarter frame message via the given device. +`public void `[`midi_send_songposition`](#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t pos)` | Send a song position message via the given device. +`public void `[`midi_send_songselect`](#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t song)` | Send a song select message via the given device. +`public void `[`midi_send_tunerequest`](#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` | Send a tune request message via the given device. +`public void `[`midi_send_byte`](#group__send__functions_1ga857e85eb90b288385642d4d991e09881)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t b)` | Send a byte via the given device. +`public void `[`midi_send_data`](#group__send__functions_1ga36e2f2e45369d911b76969361679054b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t count,uint8_t byte0,uint8_t byte1,uint8_t byte2)` | Send up to 3 bytes of data. +`public void `[`midi_send_array`](#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t count,uint8_t * array)` | Send an array of formatted midi data. + +## Members + +#### `public void `[`midi_send_cc`](#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t val)` {#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960} + +Send a control change message (cc) via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `num` the cc num + +* `val` the value of that cc num + +#### `public void `[`midi_send_noteon`](#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` {#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775} + +Send a note on message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `num` the note number + +* `vel` the note velocity + +#### `public void `[`midi_send_noteoff`](#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` {#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49} + +Send a note off message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `num` the note number + +* `vel` the note velocity + +#### `public void `[`midi_send_aftertouch`](#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t note_num,uint8_t amt)` {#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f} + +Send an after touch message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `note_num` the note number + +* `amt` the after touch amount + +#### `public void `[`midi_send_pitchbend`](#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,int16_t amt)` {#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491} + +Send a pitch bend message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `amt` the bend amount range: -8192..8191, 0 means no bend + +#### `public void `[`midi_send_programchange`](#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t num)` {#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86} + +Send a program change message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `num` the program to change to + +#### `public void `[`midi_send_channelpressure`](#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t chan,uint8_t amt)` {#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b} + +Send a channel pressure message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `chan` the channel to send on, 0-15 + +* `amt` the amount of channel pressure + +#### `public void `[`midi_send_clock`](#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa} + +Send a clock message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_tick`](#group__send__functions_1ga2b43c7d433d940c5b907595aac947972)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga2b43c7d433d940c5b907595aac947972} + +Send a tick message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_start`](#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc} + +Send a start message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_continue`](#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120} + +Send a continue message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_stop`](#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988} + +Send a stop message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_activesense`](#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37} + +Send an active sense message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_reset`](#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b} + +Send a reset message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_tcquarterframe`](#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t time)` {#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a} + +Send a tc quarter frame message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `time` the time of this quarter frame, range 0..16383 + +#### `public void `[`midi_send_songposition`](#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t pos)` {#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f} + +Send a song position message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `pos` the song position + +#### `public void `[`midi_send_songselect`](#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t song)` {#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50} + +Send a song select message via the given device. + +#### Parameters +* `device` the device to use for sending + +* `song` the song to select + +#### `public void `[`midi_send_tunerequest`](#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device)` {#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656} + +Send a tune request message via the given device. + +#### Parameters +* `device` the device to use for sending + +#### `public void `[`midi_send_byte`](#group__send__functions_1ga857e85eb90b288385642d4d991e09881)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint8_t b)` {#group__send__functions_1ga857e85eb90b288385642d4d991e09881} + +Send a byte via the given device. + +This is a generic method for sending data via the given midi device. This would be useful for sending sysex data or messages that are not implemented in this API, if there are any. Please contact the author if you find some so we can add them. + +#### Parameters +* `device` the device to use for sending + +* `b` the byte to send + +#### `public void `[`midi_send_data`](#group__send__functions_1ga36e2f2e45369d911b76969361679054b)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t count,uint8_t byte0,uint8_t byte1,uint8_t byte2)` {#group__send__functions_1ga36e2f2e45369d911b76969361679054b} + +Send up to 3 bytes of data. + +% 4 is applied to count so that you can use this to pass sysex through + +#### Parameters +* `device` the device to use for sending + +* `count` the count of bytes to send, %4 is applied + +* `byte0` the first byte + +* `byte1` the second byte, ignored if cnt % 4 != 2 + +* `byte2` the third byte, ignored if cnt % 4 != 3 + +#### `public void `[`midi_send_array`](#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead)`(`[`MidiDevice`](.build/docs/internals_midi_device.md#struct__midi__device)` * device,uint16_t count,uint8_t * array)` {#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead} + +Send an array of formatted midi data. + +Can be used for sysex. + +#### Parameters +* `device` the device to use for sending + +* `count` the count of bytes to send + +* `array` the array of bytes + diff --git a/internals_sysex_tools.md b/internals_sysex_tools.md new file mode 100644 index 00000000000..55dbe9e1644 --- /dev/null +++ b/internals_sysex_tools.md @@ -0,0 +1,61 @@ +# group `sysex_tools` {#group__sysex__tools} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint16_t `[`sysex_encoded_length`](#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a)`(uint16_t decoded_length)` | Compute the length of a message after it is encoded. +`public uint16_t `[`sysex_decoded_length`](#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0)`(uint16_t encoded_length)` | Compute the length of a message after it is decoded. +`public uint16_t `[`sysex_encode`](#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742)`(uint8_t * encoded,const uint8_t * source,uint16_t length)` | Encode data so that it can be transmitted safely in a sysex message. +`public uint16_t `[`sysex_decode`](#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229)`(uint8_t * decoded,const uint8_t * source,uint16_t length)` | Decode encoded data. + +## Members + +#### `public uint16_t `[`sysex_encoded_length`](#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a)`(uint16_t decoded_length)` {#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a} + +Compute the length of a message after it is encoded. + +#### Parameters +* `decoded_length` The length, in bytes, of the message to encode. + +#### Returns +The length, in bytes, of the message after encodeing. + +#### `public uint16_t `[`sysex_decoded_length`](#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0)`(uint16_t encoded_length)` {#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0} + +Compute the length of a message after it is decoded. + +#### Parameters +* `encoded_length` The length, in bytes, of the encoded message. + +#### Returns +The length, in bytes, of the message after it is decoded. + +#### `public uint16_t `[`sysex_encode`](#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742)`(uint8_t * encoded,const uint8_t * source,uint16_t length)` {#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742} + +Encode data so that it can be transmitted safely in a sysex message. + +#### Parameters +* `encoded` The output data buffer, must be at least sysex_encoded_length(length) bytes long. + +* `source` The input buffer of data to be encoded. + +* `length` The number of bytes from the input buffer to encode. + +#### Returns +number of bytes encoded. + +#### `public uint16_t `[`sysex_decode`](#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229)`(uint8_t * decoded,const uint8_t * source,uint16_t length)` {#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229} + +Decode encoded data. + +#### Parameters +* `decoded` The output data buffer, must be at least sysex_decoded_length(length) bytes long. + +* `source` The input buffer of data to be decoded. + +* `length` The number of bytes from the input buffer to decode. + +#### Returns +number of bytes decoded. + diff --git a/internals_udc_desc_group.md b/internals_udc_desc_group.md new file mode 100644 index 00000000000..361d269790e --- /dev/null +++ b/internals_udc_desc_group.md @@ -0,0 +1,79 @@ +# group `udc_desc_group` {#group__udc__desc__group} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`UDC_DESC_STORAGE`](#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f) | Defines the memory's location of USB descriptors. +`define `[`UDC_DATA`](#group__udc__desc__group_1ga1659a2f0b429f07a985a8faaa3fb27b1) | +`define `[`UDC_BSS`](#group__udc__desc__group_1ga198e5cdf3367aa0b35821417b7ede0b2) | +`struct `[`udc_config_speed_t`](#structudc__config__speed__t) | Configuration descriptor and UDI link for one USB speed. +`struct `[`udc_config_t`](#structudc__config__t) | All information about the USB Device. + +## Members + +#### `define `[`UDC_DESC_STORAGE`](#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f) {#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f} + +Defines the memory's location of USB descriptors. + +By default the Descriptor is stored in RAM (UDC_DESC_STORAGE is defined empty). + +If you have need to free RAM space, it is possible to put descriptor in flash in following case: + +* USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + +* USB Device is not high speed (UDC no need to change USB descriptors) + +For UC3 application used "const". + +For Mega application used "code". + +#### `define `[`UDC_DATA`](#group__udc__desc__group_1ga1659a2f0b429f07a985a8faaa3fb27b1) {#group__udc__desc__group_1ga1659a2f0b429f07a985a8faaa3fb27b1} + +#### `define `[`UDC_BSS`](#group__udc__desc__group_1ga198e5cdf3367aa0b35821417b7ede0b2) {#group__udc__desc__group_1ga198e5cdf3367aa0b35821417b7ede0b2} + +# struct `udc_config_speed_t` {#structudc__config__speed__t} + +Configuration descriptor and UDI link for one USB speed. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`desc`](#structudc__config__speed__t_1a6603d52f85ab88bc45af669a01c4b73a) | USB configuration descriptor. +`public `[`udi_api_t](.build/docs/internals_udi_group.md#structudi__api__t)[UDC_DESC_STORAGE](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f) *[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udi_apis`](#structudc__config__speed__t_1a6b3a118ab8cad1b5fd0a3a1e8cf2ba36) | Array of UDI API pointer. + +## Members + +#### `public `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`desc`](#structudc__config__speed__t_1a6603d52f85ab88bc45af669a01c4b73a) {#structudc__config__speed__t_1a6603d52f85ab88bc45af669a01c4b73a} + +USB configuration descriptor. + +#### `public `[`udi_api_t](.build/docs/internals_udi_group.md#structudi__api__t)[UDC_DESC_STORAGE](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f) *[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udi_apis`](#structudc__config__speed__t_1a6b3a118ab8cad1b5fd0a3a1e8cf2ba36) {#structudc__config__speed__t_1a6b3a118ab8cad1b5fd0a3a1e8cf2ba36} + +Array of UDI API pointer. + +# struct `udc_config_t` {#structudc__config__t} + +All information about the USB Device. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_dev_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__dev__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`confdev_lsfs`](#structudc__config__t_1af7a4ce04947ddceb4c621cfd1da6e19f) | USB device descriptor for low or full speed. +`public `[`udc_config_speed_t](.build/docs/internals_udc_desc_group.md#structudc__config__speed__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`conf_lsfs`](#structudc__config__t_1a5f1714368d3c5fc176c1d31705e8ab89) | USB configuration descriptor and UDI API pointers for low or full speed. +`public `[`usb_dev_bos_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__dev__bos__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`conf_bos`](#structudc__config__t_1a1618a7226bcdbef10cf749598ce5d2af) | + +## Members + +#### `public `[`usb_dev_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__dev__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`confdev_lsfs`](#structudc__config__t_1af7a4ce04947ddceb4c621cfd1da6e19f) {#structudc__config__t_1af7a4ce04947ddceb4c621cfd1da6e19f} + +USB device descriptor for low or full speed. + +#### `public `[`udc_config_speed_t](.build/docs/internals_udc_desc_group.md#structudc__config__speed__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`conf_lsfs`](#structudc__config__t_1a5f1714368d3c5fc176c1d31705e8ab89) {#structudc__config__t_1a5f1714368d3c5fc176c1d31705e8ab89} + +USB configuration descriptor and UDI API pointers for low or full speed. + +#### `public `[`usb_dev_bos_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__dev__bos__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`conf_bos`](#structudc__config__t_1a1618a7226bcdbef10cf749598ce5d2af) {#structudc__config__t_1a1618a7226bcdbef10cf749598ce5d2af} + diff --git a/internals_udc_group.md b/internals_udc_group.md new file mode 100644 index 00000000000..2221736a90d --- /dev/null +++ b/internals_udc_group.md @@ -0,0 +1,148 @@ +# group `udc_group` {#group__udc__group} + +The UDC provides a high-level abstraction of the usb device. You can use these functions to control the main device state (start/attach/wakeup). + +USB Device Custom configurationThe following USB Device configuration must be included in the [conf_usb.h](.build/docs/internals_undefined.md#conf__usb_8h) file of the application. + +USB_DEVICE_VENDOR_ID (Word) + Vendor ID provided by USB org (ATMEL 0x03EB). + +USB_DEVICE_PRODUCT_ID (Word) + Product ID (Referenced in [usb_atmel.h](.build/docs/internals_undefined.md#usb__atmel_8h)). + +USB_DEVICE_MAJOR_VERSION (Byte) + Major version of the device + +USB_DEVICE_MINOR_VERSION (Byte) + Minor version of the device + +USB_DEVICE_MANUFACTURE_NAME (string) + ASCII name for the manufacture + +USB_DEVICE_PRODUCT_NAME (string) + ASCII name for the product + +USB_DEVICE_SERIAL_NAME (string) + ASCII name to enable and set a serial number + +USB_DEVICE_POWER (Numeric) + (unit mA) Maximum device power + +USB_DEVICE_ATTR (Byte) + USB attributes available: + +* USB_CONFIG_ATTR_SELF_POWERED + +* USB_CONFIG_ATTR_REMOTE_WAKEUP Note: if remote wake enabled then defines remotewakeup callbacks, see Table 5-2. External API from UDC - Callback + +USB_DEVICE_LOW_SPEED (Only defined) + Force the USB Device to run in low speed + +USB_DEVICE_HS_SUPPORT (Only defined) + Authorize the USB Device to run in high speed + +USB_DEVICE_MAX_EP (Byte) + Define the maximum endpoint number used by the USB Device. + This one is already defined in UDI default configuration. Ex: + +* When endpoint control 0x00, endpoint 0x01 and endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + +* When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + +* When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1 + (configuration not possible on USBB interface) + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public inline static bool `[`udc_include_vbus_monitoring`](#group__udc__group_1ga70d88509bac27ef9c25f693dd21d91ca)`(void)` | Authorizes the VBUS event. +`public void `[`udc_start`](#group__udc__group_1gadf4e193509cd03ab6333d62629ea51e7)`(void)` | Start the USB Device stack. +`public void `[`udc_stop`](#group__udc__group_1gae2264dd91b24db9d4bb23fb1a2014972)`(void)` | Stop the USB Device stack. +`public inline static void `[`udc_attach`](#group__udc__group_1ga2e71c4c6090543bc3bab06e710e2ee6b)`(void)` | Attach device to the bus when possible. +`public inline static void `[`udc_detach`](#group__udc__group_1ga702d387f5ebfc2e0ab41667eb7644dda)`(void)` | Detaches the device from the bus. +`public inline void `[`udc_remotewakeup`](#group__udc__group_1ga52c0439e5f6e471a9570471f00476260)`(void)` | The USB driver sends a resume signal called *"Upstream Resume"* This is authorized only when the remote wakeup feature is enabled by host. +`public `[`usb_iface_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__iface__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_interface_desc`](#group__udc__group_1gadb2a0f5ad1e834d4d7e7777f901d64d2)`(void)` | Returns a pointer on the current interface descriptor. + +## Members + +#### `public inline static bool `[`udc_include_vbus_monitoring`](#group__udc__group_1ga70d88509bac27ef9c25f693dd21d91ca)`(void)` {#group__udc__group_1ga70d88509bac27ef9c25f693dd21d91ca} + +Authorizes the VBUS event. + +#### Returns +true, if the VBUS monitoring is possible. + +VBus monitoring used casesThe VBus monitoring is used only for USB SELF Power application. + +* By default the USB device is automatically attached when Vbus is high or when USB is start for devices without internal Vbus monitoring. [conf_usb.h](.build/docs/internals_undefined.md#conf__usb_8h) file does not contains define USB_DEVICE_ATTACH_AUTO_DISABLE. +```cpp +//#define USB_DEVICE_ATTACH_AUTO_DISABLE +``` + +* Add custom VBUS monitoring. [conf_usb.h](.build/docs/internals_undefined.md#conf__usb_8h) file contains define USB_DEVICE_ATTACH_AUTO_DISABLE: +```cpp +#define USB_DEVICE_ATTACH_AUTO_DISABLE +``` + User C file contains: +```cpp +// Authorize VBUS monitoring +if (!udc_include_vbus_monitoring()) { + // Implement custom VBUS monitoring via GPIO or other +} +Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other +{ + // Attach USB Device + udc_attach(); +} +``` + +* Case of battery charging. [conf_usb.h](.build/docs/internals_undefined.md#conf__usb_8h) file contains define USB_DEVICE_ATTACH_AUTO_DISABLE: +```cpp +#define USB_DEVICE_ATTACH_AUTO_DISABLE +``` + User C file contains: +```cpp +Event VBUS present() // VBUS interrupt or GPIO interrupt or .. +{ + // Authorize battery charging, but wait key press to start USB. +} +Event Key press() +{ + // Stop batteries charging + // Start USB + udc_attach(); +} +``` + +#### `public void `[`udc_start`](#group__udc__group_1gadf4e193509cd03ab6333d62629ea51e7)`(void)` {#group__udc__group_1gadf4e193509cd03ab6333d62629ea51e7} + +Start the USB Device stack. + +#### `public void `[`udc_stop`](#group__udc__group_1gae2264dd91b24db9d4bb23fb1a2014972)`(void)` {#group__udc__group_1gae2264dd91b24db9d4bb23fb1a2014972} + +Stop the USB Device stack. + +#### `public inline static void `[`udc_attach`](#group__udc__group_1ga2e71c4c6090543bc3bab06e710e2ee6b)`(void)` {#group__udc__group_1ga2e71c4c6090543bc3bab06e710e2ee6b} + +Attach device to the bus when possible. + +If a VBus control is included in driver, then it will attach device when an acceptable Vbus level from the host is detected. + +#### `public inline static void `[`udc_detach`](#group__udc__group_1ga702d387f5ebfc2e0ab41667eb7644dda)`(void)` {#group__udc__group_1ga702d387f5ebfc2e0ab41667eb7644dda} + +Detaches the device from the bus. + +The driver must remove pull-up on USB line D- or D+. + +#### `public inline void `[`udc_remotewakeup`](#group__udc__group_1ga52c0439e5f6e471a9570471f00476260)`(void)` {#group__udc__group_1ga52c0439e5f6e471a9570471f00476260} + +The USB driver sends a resume signal called *"Upstream Resume"* This is authorized only when the remote wakeup feature is enabled by host. + +#### `public `[`usb_iface_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__iface__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_interface_desc`](#group__udc__group_1gadb2a0f5ad1e834d4d7e7777f901d64d2)`(void)` {#group__udc__group_1gadb2a0f5ad1e834d4d7e7777f901d64d2} + +Returns a pointer on the current interface descriptor. + +#### Returns +pointer on the current interface descriptor. + diff --git a/internals_udc_group_interne.md b/internals_udc_group_interne.md new file mode 100644 index 00000000000..84632082892 --- /dev/null +++ b/internals_udc_group_interne.md @@ -0,0 +1,267 @@ +# group `udc_group_interne` {#group__udc__group__interne} + +Internal implementation + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_iface_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__iface__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_interface_desc`](#group__udc__group__interne_1gadb2a0f5ad1e834d4d7e7777f901d64d2)`(void)` | Returns a pointer on the current interface descriptor. +`public static `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_eof_conf`](#group__udc__group__interne_1ga3442594fd7435c3803460847014c8970)`(void)` | Returns a value to check the end of USB Configuration descriptor. +`public static `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_next_desc_in_iface`](#group__udc__group__interne_1ga5b377861e784ec69c3e841643169a981)`(`[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * desc,uint8_t desc_id)` | Search specific descriptor in global interface descriptor. +`public static bool `[`udc_update_iface_desc`](#group__udc__group__interne_1gab6a52be155f35da55d33d3474f06cc47)`(uint8_t iface_num,uint8_t setting_num)` | Search an interface descriptor This routine updates the internal pointer udc_ptr_iface. +`public static bool `[`udc_iface_disable`](#group__udc__group__interne_1ga4d8c4886411e5f90adaac8bff065c610)`(uint8_t iface_num)` | Disables an usb device interface (UDI) This routine call the UDI corresponding to interface number. +`public static bool `[`udc_iface_enable`](#group__udc__group__interne_1gab7d44215050fc758b44c86dc88a16264)`(uint8_t iface_num,uint8_t setting_num)` | Enables an usb device interface (UDI) This routine calls the UDI corresponding to the interface and setting number. +`public void `[`udc_start`](#group__udc__group__interne_1gadf4e193509cd03ab6333d62629ea51e7)`(void)` | Start the USB Device stack. +`public void `[`udc_stop`](#group__udc__group__interne_1gae2264dd91b24db9d4bb23fb1a2014972)`(void)` | Stop the USB Device stack. +`public void `[`udc_reset`](#group__udc__group__interne_1ga11a32ff7928ba06d3b59e95e0a2b7a92)`(void)` | Reset the current configuration of the USB device, This routines can be called by UDD when a RESET on the USB line occurs. +`public void `[`udc_sof_notify`](#group__udc__group__interne_1ga4afae313045f44b5eb4c60957ab8ef4e)`(void)` | To signal that a SOF is occurred. +`public static bool `[`udc_req_std_dev_get_status`](#group__udc__group__interne_1gad6531ffd8e25d5b7492a7a7f4f89ea3f)`(void)` | Standard device request to get device status. +`public static bool `[`udc_req_std_ep_get_status`](#group__udc__group__interne_1ga97951f0c157b56a0bdb2c1ee01ef28c7)`(void)` | Standard endpoint request to get endpoint status. +`public static bool `[`udc_req_std_dev_clear_feature`](#group__udc__group__interne_1gace4de90bb4ef13b7aede71038a5e1dcb)`(void)` | Standard device request to change device status. +`public static bool `[`udc_req_std_ep_clear_feature`](#group__udc__group__interne_1ga59d4bc22153641a20eb48f8407e9c099)`(void)` | Standard endpoint request to clear endpoint feature. +`public static bool `[`udc_req_std_dev_set_feature`](#group__udc__group__interne_1gadd42bf8a4178b3e06f78966a6323108d)`(void)` | Standard device request to set a feature. +`public static bool `[`udc_req_std_ep_set_feature`](#group__udc__group__interne_1ga11f8eef1ab88fe1d029414f039508661)`(void)` | Standard endpoint request to halt an endpoint. +`public static void `[`udc_valid_address`](#group__udc__group__interne_1ga8b6715772a604a998846a3aa97c042c2)`(void)` | Change the address of device Callback called at the end of request set address. +`public static bool `[`udc_req_std_dev_set_address`](#group__udc__group__interne_1gaa800b0a860337f155b43b86444f43809)`(void)` | Standard device request to set device address. +`public static bool `[`udc_req_std_dev_get_str_desc`](#group__udc__group__interne_1gaf13a0b91b1ec15e4aae33a7d5df2be64)`(void)` | Standard device request to get device string descriptor. +`public static bool `[`udc_req_std_dev_get_descriptor`](#group__udc__group__interne_1gae46c685525dbe2a47ed7acdabda5f094)`(void)` | Standard device request to get descriptors about USB device. +`public static bool `[`udc_req_std_dev_get_configuration`](#group__udc__group__interne_1gadd826de0797aae1e872f44a6a9ee81da)`(void)` | Standard device request to get configuration number. +`public static bool `[`udc_req_std_dev_set_configuration`](#group__udc__group__interne_1ga0da31a19fcd81e03a9b0d6ba17a2cdc4)`(void)` | Standard device request to enable a configuration. +`public static bool `[`udc_req_std_iface_get_setting`](#group__udc__group__interne_1gac9f53c587375a24ac6b63206d650f36c)`(void)` | Standard interface request to get the alternate setting number of an interface. +`public static bool `[`udc_req_std_iface_set_setting`](#group__udc__group__interne_1gad06f93d41064705e7f6fd992fef1230f)`(void)` | Standard interface request to set an alternate setting of an interface. +`public static bool `[`udc_reqstd`](#group__udc__group__interne_1gac82ad471b5bfa644309f98815757c867)`(void)` | Main routine to manage the standard USB SETUP request. +`public static bool `[`udc_req_iface`](#group__udc__group__interne_1ga920a557a9121c44513deceb2f9358fc1)`(void)` | Send the SETUP interface request to UDI. +`public static bool `[`udc_req_ep`](#group__udc__group__interne_1ga640a2df7bb1c1fbed895286a8513663c)`(void)` | Send the SETUP interface request to UDI. +`public bool `[`udc_process_setup`](#group__udc__group__interne_1ga58c2916d7984e0e5b2143cadf4af6080)`(void)` | Main routine to manage the USB SETUP request. +`struct `[`udc_string_desc_t`](#structudc__string__desc__t) | + +## Members + +#### `public `[`usb_iface_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__iface__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_interface_desc`](#group__udc__group__interne_1gadb2a0f5ad1e834d4d7e7777f901d64d2)`(void)` {#group__udc__group__interne_1gadb2a0f5ad1e834d4d7e7777f901d64d2} + +Returns a pointer on the current interface descriptor. + +#### Returns +pointer on the current interface descriptor. + +#### `public static `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_get_eof_conf`](#group__udc__group__interne_1ga3442594fd7435c3803460847014c8970)`(void)` {#group__udc__group__interne_1ga3442594fd7435c3803460847014c8970} + +Returns a value to check the end of USB Configuration descriptor. + +#### Returns +address after the last byte of USB Configuration descriptor + +#### `public static `[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * `[`udc_next_desc_in_iface`](#group__udc__group__interne_1ga5b377861e784ec69c3e841643169a981)`(`[`usb_conf_desc_t](.build/docs/internals_usb_protocol_group.md#structusb__conf__desc__t)[UDC_DESC_STORAGE`](.build/docs/internals_undefined.md#group__udc__desc__group_1gae086959cec07a2e71ab069e25a51764f)` * desc,uint8_t desc_id)` {#group__udc__group__interne_1ga5b377861e784ec69c3e841643169a981} + +Search specific descriptor in global interface descriptor. + +#### Parameters +* `desc` Address of interface descriptor or previous specific descriptor found + +* `desc_id` Descriptor ID to search + +#### Returns +address of specific descriptor found + +#### Returns +NULL if it is the end of global interface descriptor + +#### `public static bool `[`udc_update_iface_desc`](#group__udc__group__interne_1gab6a52be155f35da55d33d3474f06cc47)`(uint8_t iface_num,uint8_t setting_num)` {#group__udc__group__interne_1gab6a52be155f35da55d33d3474f06cc47} + +Search an interface descriptor This routine updates the internal pointer udc_ptr_iface. + +#### Parameters +* `iface_num` Interface number to find in Configuration Descriptor + +* `setting_num` Setting number of interface to find + +#### Returns +1 if found or 0 if not found + +#### `public static bool `[`udc_iface_disable`](#group__udc__group__interne_1ga4d8c4886411e5f90adaac8bff065c610)`(uint8_t iface_num)` {#group__udc__group__interne_1ga4d8c4886411e5f90adaac8bff065c610} + +Disables an usb device interface (UDI) This routine call the UDI corresponding to interface number. + +#### Parameters +* `iface_num` Interface number to disable + +#### Returns +1 if it is done or 0 if interface is not found + +#### `public static bool `[`udc_iface_enable`](#group__udc__group__interne_1gab7d44215050fc758b44c86dc88a16264)`(uint8_t iface_num,uint8_t setting_num)` {#group__udc__group__interne_1gab7d44215050fc758b44c86dc88a16264} + +Enables an usb device interface (UDI) This routine calls the UDI corresponding to the interface and setting number. + +#### Parameters +* `iface_num` Interface number to enable + +* `setting_num` Setting number to enable + +#### Returns +1 if it is done or 0 if interface is not found + +#### `public void `[`udc_start`](#group__udc__group__interne_1gadf4e193509cd03ab6333d62629ea51e7)`(void)` {#group__udc__group__interne_1gadf4e193509cd03ab6333d62629ea51e7} + +Start the USB Device stack. + +#### `public void `[`udc_stop`](#group__udc__group__interne_1gae2264dd91b24db9d4bb23fb1a2014972)`(void)` {#group__udc__group__interne_1gae2264dd91b24db9d4bb23fb1a2014972} + +Stop the USB Device stack. + +#### `public void `[`udc_reset`](#group__udc__group__interne_1ga11a32ff7928ba06d3b59e95e0a2b7a92)`(void)` {#group__udc__group__interne_1ga11a32ff7928ba06d3b59e95e0a2b7a92} + +Reset the current configuration of the USB device, This routines can be called by UDD when a RESET on the USB line occurs. + +Reset the UDC. + +#### `public void `[`udc_sof_notify`](#group__udc__group__interne_1ga4afae313045f44b5eb4c60957ab8ef4e)`(void)` {#group__udc__group__interne_1ga4afae313045f44b5eb4c60957ab8ef4e} + +To signal that a SOF is occurred. + +The UDC must send the signal to all UDIs enabled + +#### `public static bool `[`udc_req_std_dev_get_status`](#group__udc__group__interne_1gad6531ffd8e25d5b7492a7a7f4f89ea3f)`(void)` {#group__udc__group__interne_1gad6531ffd8e25d5b7492a7a7f4f89ea3f} + +Standard device request to get device status. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_ep_get_status`](#group__udc__group__interne_1ga97951f0c157b56a0bdb2c1ee01ef28c7)`(void)` {#group__udc__group__interne_1ga97951f0c157b56a0bdb2c1ee01ef28c7} + +Standard endpoint request to get endpoint status. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_clear_feature`](#group__udc__group__interne_1gace4de90bb4ef13b7aede71038a5e1dcb)`(void)` {#group__udc__group__interne_1gace4de90bb4ef13b7aede71038a5e1dcb} + +Standard device request to change device status. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_ep_clear_feature`](#group__udc__group__interne_1ga59d4bc22153641a20eb48f8407e9c099)`(void)` {#group__udc__group__interne_1ga59d4bc22153641a20eb48f8407e9c099} + +Standard endpoint request to clear endpoint feature. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_set_feature`](#group__udc__group__interne_1gadd42bf8a4178b3e06f78966a6323108d)`(void)` {#group__udc__group__interne_1gadd42bf8a4178b3e06f78966a6323108d} + +Standard device request to set a feature. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_ep_set_feature`](#group__udc__group__interne_1ga11f8eef1ab88fe1d029414f039508661)`(void)` {#group__udc__group__interne_1ga11f8eef1ab88fe1d029414f039508661} + +Standard endpoint request to halt an endpoint. + +#### Returns +true if success + +#### `public static void `[`udc_valid_address`](#group__udc__group__interne_1ga8b6715772a604a998846a3aa97c042c2)`(void)` {#group__udc__group__interne_1ga8b6715772a604a998846a3aa97c042c2} + +Change the address of device Callback called at the end of request set address. + +#### `public static bool `[`udc_req_std_dev_set_address`](#group__udc__group__interne_1gaa800b0a860337f155b43b86444f43809)`(void)` {#group__udc__group__interne_1gaa800b0a860337f155b43b86444f43809} + +Standard device request to set device address. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_get_str_desc`](#group__udc__group__interne_1gaf13a0b91b1ec15e4aae33a7d5df2be64)`(void)` {#group__udc__group__interne_1gaf13a0b91b1ec15e4aae33a7d5df2be64} + +Standard device request to get device string descriptor. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_get_descriptor`](#group__udc__group__interne_1gae46c685525dbe2a47ed7acdabda5f094)`(void)` {#group__udc__group__interne_1gae46c685525dbe2a47ed7acdabda5f094} + +Standard device request to get descriptors about USB device. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_get_configuration`](#group__udc__group__interne_1gadd826de0797aae1e872f44a6a9ee81da)`(void)` {#group__udc__group__interne_1gadd826de0797aae1e872f44a6a9ee81da} + +Standard device request to get configuration number. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_dev_set_configuration`](#group__udc__group__interne_1ga0da31a19fcd81e03a9b0d6ba17a2cdc4)`(void)` {#group__udc__group__interne_1ga0da31a19fcd81e03a9b0d6ba17a2cdc4} + +Standard device request to enable a configuration. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_iface_get_setting`](#group__udc__group__interne_1gac9f53c587375a24ac6b63206d650f36c)`(void)` {#group__udc__group__interne_1gac9f53c587375a24ac6b63206d650f36c} + +Standard interface request to get the alternate setting number of an interface. + +#### Returns +true if success + +#### `public static bool `[`udc_req_std_iface_set_setting`](#group__udc__group__interne_1gad06f93d41064705e7f6fd992fef1230f)`(void)` {#group__udc__group__interne_1gad06f93d41064705e7f6fd992fef1230f} + +Standard interface request to set an alternate setting of an interface. + +#### Returns +true if success + +#### `public static bool `[`udc_reqstd`](#group__udc__group__interne_1gac82ad471b5bfa644309f98815757c867)`(void)` {#group__udc__group__interne_1gac82ad471b5bfa644309f98815757c867} + +Main routine to manage the standard USB SETUP request. + +#### Returns +true if the request is supported + +#### `public static bool `[`udc_req_iface`](#group__udc__group__interne_1ga920a557a9121c44513deceb2f9358fc1)`(void)` {#group__udc__group__interne_1ga920a557a9121c44513deceb2f9358fc1} + +Send the SETUP interface request to UDI. + +#### Returns +true if the request is supported + +#### `public static bool `[`udc_req_ep`](#group__udc__group__interne_1ga640a2df7bb1c1fbed895286a8513663c)`(void)` {#group__udc__group__interne_1ga640a2df7bb1c1fbed895286a8513663c} + +Send the SETUP interface request to UDI. + +#### Returns +true if the request is supported + +#### `public bool `[`udc_process_setup`](#group__udc__group__interne_1ga58c2916d7984e0e5b2143cadf4af6080)`(void)` {#group__udc__group__interne_1ga58c2916d7984e0e5b2143cadf4af6080} + +Main routine to manage the USB SETUP request. + +Decodes and manages a setup request. + +This function parses a USB SETUP request and submits an appropriate response back to the host or, in the case of SETUP OUT requests with data, sets up a buffer for receiving the data payload. + +The main standard requests defined by the USB 2.0 standard are handled internally. The interface requests are sent to UDI, and the specific request sent to a specific application callback. + +#### Returns +true if the request is supported, else the request is stalled by UDD + +# struct `udc_string_desc_t` {#structudc__string__desc__t} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_str_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__str__desc__t)` `[`header`](#structudc__string__desc__t_1ae96103b577725a05178dac3136d1a859) | +`public le16_t `[`string`](#structudc__string__desc__t_1a9c4b5919e84bf0e87ea42a502f4dd74c) | + +## Members + +#### `public `[`usb_str_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__str__desc__t)` `[`header`](#structudc__string__desc__t_1ae96103b577725a05178dac3136d1a859) {#structudc__string__desc__t_1ae96103b577725a05178dac3136d1a859} + +#### `public le16_t `[`string`](#structudc__string__desc__t_1a9c4b5919e84bf0e87ea42a502f4dd74c) {#structudc__string__desc__t_1a9c4b5919e84bf0e87ea42a502f4dd74c} + diff --git a/internals_udd_group.md b/internals_udd_group.md new file mode 100644 index 00000000000..60d67bc745f --- /dev/null +++ b/internals_udd_group.md @@ -0,0 +1,171 @@ +# group `udd_group` {#group__udd__group} + +The UDD driver provides a low-level abstraction of the device controller hardware. Most events coming from the hardware such as interrupts, which may cause the UDD to call into the UDC and UDI. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`Udd_setup_is_in`](#group__udd__group_1gaffd9b7cf165cd149868373fa12595d12) | Return true if the setup request *udd_g_ctrlreq* indicates IN data transfer. +`define `[`Udd_setup_is_out`](#group__udd__group_1gaf67b7c8de30fdc881b567385f2345926) | Return true if the setup request *udd_g_ctrlreq* indicates OUT data transfer. +`define `[`Udd_setup_type`](#group__udd__group_1ga85dc2b7b6c270e8dd8323fa4779a7ca2) | Return the type of the SETUP request *udd_g_ctrlreq*. +`define `[`Udd_setup_recipient`](#group__udd__group_1gac963bb7b8a965c2fec45a71c9faca6f5) | Return the recipient of the SETUP request *udd_g_ctrlreq*. +`enum `[`udd_ep_status_t`](#group__udd__group_1gac0f77f5a0e085af1242b48fd1054959a) | Endpoint transfer status Returned in parameters of callback register via udd_ep_run routine. +`public bool `[`udd_include_vbus_monitoring`](#group__udd__group_1gaa4cac8c35ae056e26cf4ab5b426bbe09)`(void)` | Authorizes the VBUS event. +`public void `[`udd_enable`](#group__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42)`(void)` | Enables the USB Device mode. +`public void `[`udd_disable`](#group__udd__group_1gab283432057b934e9d73ac9282d9b0f11)`(void)` | Disables the USB Device mode. +`public void `[`udd_attach`](#group__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f)`(void)` | Attach device to the bus when possible. +`public void `[`udd_detach`](#group__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e)`(void)` | Detaches the device from the bus. +`public bool `[`udd_is_high_speed`](#group__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c)`(void)` | Test whether the USB Device Controller is running at high speed or not. +`public void `[`udd_set_address`](#group__udd__group_1ga05da762e0faf9d478e532de40afa71f6)`(uint8_t address)` | Changes the USB address of device. +`public uint8_t `[`udd_getaddress`](#group__udd__group_1gaebd36638d482f6df00a8aff006ef2246)`(void)` | Returns the USB address of device. +`public uint16_t `[`udd_get_frame_number`](#group__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320)`(void)` | Returns the current start of frame number. +`public uint16_t `[`udd_get_micro_frame_number`](#group__udd__group_1ga63047eec59b8e8798ca1d3366472d82b)`(void)` | Returns the current micro start of frame number. +`public void `[`udd_send_remotewakeup`](#group__udd__group_1gac447212e04789282dabee65a23fe2a08)`(void)` | The USB driver sends a resume signal called Upstream Resume. +`public void `[`udd_set_setup_payload`](#group__udd__group_1ga017ef5ea7626be258c24d345218976f9)`(uint8_t * payload,uint16_t payload_size)` | Load setup payload. +`struct `[`udd_ctrl_request_t`](#structudd__ctrl__request__t) | Global variable to give and record information of the setup request management. + +## Members + +#### `define `[`Udd_setup_is_in`](#group__udd__group_1gaffd9b7cf165cd149868373fa12595d12) {#group__udd__group_1gaffd9b7cf165cd149868373fa12595d12} + +Return true if the setup request *udd_g_ctrlreq* indicates IN data transfer. + +#### `define `[`Udd_setup_is_out`](#group__udd__group_1gaf67b7c8de30fdc881b567385f2345926) {#group__udd__group_1gaf67b7c8de30fdc881b567385f2345926} + +Return true if the setup request *udd_g_ctrlreq* indicates OUT data transfer. + +#### `define `[`Udd_setup_type`](#group__udd__group_1ga85dc2b7b6c270e8dd8323fa4779a7ca2) {#group__udd__group_1ga85dc2b7b6c270e8dd8323fa4779a7ca2} + +Return the type of the SETUP request *udd_g_ctrlreq*. + +**See also**: usb_reqtype. + +#### `define `[`Udd_setup_recipient`](#group__udd__group_1gac963bb7b8a965c2fec45a71c9faca6f5) {#group__udd__group_1gac963bb7b8a965c2fec45a71c9faca6f5} + +Return the recipient of the SETUP request *udd_g_ctrlreq*. + +**See also**: usb_recipient + +#### `enum `[`udd_ep_status_t`](#group__udd__group_1gac0f77f5a0e085af1242b48fd1054959a) {#group__udd__group_1gac0f77f5a0e085af1242b48fd1054959a} + + Values | Descriptions +--------------------------------|--------------------------------------------- +UDD_EP_TRANSFER_OK | +UDD_EP_TRANSFER_ABORT | + +Endpoint transfer status Returned in parameters of callback register via udd_ep_run routine. + +#### `public bool `[`udd_include_vbus_monitoring`](#group__udd__group_1gaa4cac8c35ae056e26cf4ab5b426bbe09)`(void)` {#group__udd__group_1gaa4cac8c35ae056e26cf4ab5b426bbe09} + +Authorizes the VBUS event. + +#### Returns +true, if the VBUS monitoring is possible. + +#### `public void `[`udd_enable`](#group__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42)`(void)` {#group__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42} + +Enables the USB Device mode. + +#### `public void `[`udd_disable`](#group__udd__group_1gab283432057b934e9d73ac9282d9b0f11)`(void)` {#group__udd__group_1gab283432057b934e9d73ac9282d9b0f11} + +Disables the USB Device mode. + +#### `public void `[`udd_attach`](#group__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f)`(void)` {#group__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f} + +Attach device to the bus when possible. + +If a VBus control is included in driver, then it will attach device when an acceptable Vbus level from the host is detected. + +#### `public void `[`udd_detach`](#group__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e)`(void)` {#group__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e} + +Detaches the device from the bus. + +The driver must remove pull-up on USB line D- or D+. + +#### `public bool `[`udd_is_high_speed`](#group__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c)`(void)` {#group__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c} + +Test whether the USB Device Controller is running at high speed or not. + +#### Returns +`true` if the Device is running at high speed mode, otherwise `false`. + +#### `public void `[`udd_set_address`](#group__udd__group_1ga05da762e0faf9d478e532de40afa71f6)`(uint8_t address)` {#group__udd__group_1ga05da762e0faf9d478e532de40afa71f6} + +Changes the USB address of device. + +#### Parameters +* `address` New USB address + +#### `public uint8_t `[`udd_getaddress`](#group__udd__group_1gaebd36638d482f6df00a8aff006ef2246)`(void)` {#group__udd__group_1gaebd36638d482f6df00a8aff006ef2246} + +Returns the USB address of device. + +#### Returns +USB address + +#### `public uint16_t `[`udd_get_frame_number`](#group__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320)`(void)` {#group__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320} + +Returns the current start of frame number. + +#### Returns +current start of frame number. + +#### `public uint16_t `[`udd_get_micro_frame_number`](#group__udd__group_1ga63047eec59b8e8798ca1d3366472d82b)`(void)` {#group__udd__group_1ga63047eec59b8e8798ca1d3366472d82b} + +Returns the current micro start of frame number. + +#### Returns +current micro start of frame number required in high speed mode. + +#### `public void `[`udd_send_remotewakeup`](#group__udd__group_1gac447212e04789282dabee65a23fe2a08)`(void)` {#group__udd__group_1gac447212e04789282dabee65a23fe2a08} + +The USB driver sends a resume signal called Upstream Resume. + +#### `public void `[`udd_set_setup_payload`](#group__udd__group_1ga017ef5ea7626be258c24d345218976f9)`(uint8_t * payload,uint16_t payload_size)` {#group__udd__group_1ga017ef5ea7626be258c24d345218976f9} + +Load setup payload. + +#### Parameters +* `payload` Pointer on payload + +* `payload_size` Size of payload + +# struct `udd_ctrl_request_t` {#structudd__ctrl__request__t} + +Global variable to give and record information of the setup request management. + +This global variable allows to decode and response a setup request. It can be updated by [udc_process_setup()](.build/docs/internals_undefined.md#group__udc__group__interne_1ga58c2916d7984e0e5b2143cadf4af6080) from UDC or *setup() from UDIs. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_setup_req_t`](.build/docs/internals_usb_protocol_group.md#structusb__setup__req__t)` `[`req`](#structudd__ctrl__request__t_1a8ca591128eb7000ed02f8cc730af6e69) | Data received in USB SETUP packet Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. +`public uint8_t * `[`payload`](#structudd__ctrl__request__t_1aa5cbdad2c57e9b3f949e1a4d96382b66) | [Point](.build/docs/internals_undefined.md#struct_point) to buffer to send or fill with data following SETUP packet This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer) +`public uint16_t `[`payload_size`](#structudd__ctrl__request__t_1a34d21baa46ca7f4b695307631457c75f) | Size of buffer to send or fill, and content the number of byte transfered. +`public void(* `[`callback`](#structudd__ctrl__request__t_1a11f084a69a85b6e1da79695b6a3d07c3) | Callback called after reception of ZLP from setup request. +`public bool(* `[`over_under_run`](#structudd__ctrl__request__t_1a3d31b0db5458678975632d6b5815ea8c) | Callback called when the buffer given (.payload) is full or empty. This one return false to abort data transfer, or true with a new buffer in .payload. + +## Members + +#### `public `[`usb_setup_req_t`](.build/docs/internals_usb_protocol_group.md#structusb__setup__req__t)` `[`req`](#structudd__ctrl__request__t_1a8ca591128eb7000ed02f8cc730af6e69) {#structudd__ctrl__request__t_1a8ca591128eb7000ed02f8cc730af6e69} + +Data received in USB SETUP packet Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + +#### `public uint8_t * `[`payload`](#structudd__ctrl__request__t_1aa5cbdad2c57e9b3f949e1a4d96382b66) {#structudd__ctrl__request__t_1aa5cbdad2c57e9b3f949e1a4d96382b66} + +[Point](.build/docs/internals_undefined.md#struct_point) to buffer to send or fill with data following SETUP packet This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer) + +#### `public uint16_t `[`payload_size`](#structudd__ctrl__request__t_1a34d21baa46ca7f4b695307631457c75f) {#structudd__ctrl__request__t_1a34d21baa46ca7f4b695307631457c75f} + +Size of buffer to send or fill, and content the number of byte transfered. + +#### `public void(* `[`callback`](#structudd__ctrl__request__t_1a11f084a69a85b6e1da79695b6a3d07c3) {#structudd__ctrl__request__t_1a11f084a69a85b6e1da79695b6a3d07c3} + +Callback called after reception of ZLP from setup request. + +#### `public bool(* `[`over_under_run`](#structudd__ctrl__request__t_1a3d31b0db5458678975632d6b5815ea8c) {#structudd__ctrl__request__t_1a3d31b0db5458678975632d6b5815ea8c} + +Callback called when the buffer given (.payload) is full or empty. This one return false to abort data transfer, or true with a new buffer in .payload. + diff --git a/internals_udi_group.md b/internals_udi_group.md new file mode 100644 index 00000000000..3445712272c --- /dev/null +++ b/internals_udi_group.md @@ -0,0 +1,75 @@ +# group `udi_group` {#group__udi__group} + +The UDI provides a common API for all classes, and this is used by UDC for the main control of USB Device interface. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`struct `[`udi_api_t`](#structudi__api__t) | UDI API. + +# struct `udi_api_t` {#structudi__api__t} + +UDI API. + +The callbacks within this structure are called only by USB Device Controller (UDC) + +The [udc_get_interface_desc()](.build/docs/internals_undefined.md#group__udc__group__interne_1gadb2a0f5ad1e834d4d7e7777f901d64d2) can be use by UDI to know the interface descriptor selected by UDC. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public bool(* `[`enable`](#structudi__api__t_1ab2247f6571bf21eb4139a40a23c78eea) | Enable the interface. +`public void(* `[`disable`](#structudi__api__t_1ace1449d367bdcce8d6ca549dceac7a7f) | Disable the interface. +`public bool(* `[`setup`](#structudi__api__t_1a11fce471b0558711a238238dac0d5e7c) | Handle a control request directed at an interface. +`public uint8_t(* `[`getsetting`](#structudi__api__t_1a095cfc23d86008d478b6d002afbdd66a) | Returns the current setting of the selected interface. +`public void(* `[`sof_notify`](#structudi__api__t_1a9d8887d1cfbe10252f51a733cb66b9a5) | To signal that a SOF is occurred. + +## Members + +#### `public bool(* `[`enable`](#structudi__api__t_1ab2247f6571bf21eb4139a40a23c78eea) {#structudi__api__t_1ab2247f6571bf21eb4139a40a23c78eea} + +Enable the interface. + +This function is called when the host selects a configuration to which this interface belongs through a Set Configuration request, and when the host selects an alternate setting of this interface through a Set Interface request. + +#### Returns +`1` if function was successfully done, otherwise `0`. + +#### `public void(* `[`disable`](#structudi__api__t_1ace1449d367bdcce8d6ca549dceac7a7f) {#structudi__api__t_1ace1449d367bdcce8d6ca549dceac7a7f} + +Disable the interface. + +This function is called when this interface is currently active, and + +* the host selects any configuration through a Set Configuration request, or + +* the host issues a USB reset, or + +* the device is detached from the host (i.e. Vbus is no longer present) + +#### `public bool(* `[`setup`](#structudi__api__t_1a11fce471b0558711a238238dac0d5e7c) {#structudi__api__t_1a11fce471b0558711a238238dac0d5e7c} + +Handle a control request directed at an interface. + +This function is called when this interface is currently active and the host sends a SETUP request with this interface as the recipient. + +Use udd_g_ctrlreq to decode and response to SETUP request. + +#### Returns +`1` if this interface supports the SETUP request, otherwise `0`. + +#### `public uint8_t(* `[`getsetting`](#structudi__api__t_1a095cfc23d86008d478b6d002afbdd66a) {#structudi__api__t_1a095cfc23d86008d478b6d002afbdd66a} + +Returns the current setting of the selected interface. + +This function is called when UDC when know alternate setting of selected interface. + +#### Returns +alternate setting of selected interface + +#### `public void(* `[`sof_notify`](#structudi__api__t_1a9d8887d1cfbe10252f51a733cb66b9a5) {#structudi__api__t_1a9d8887d1cfbe10252f51a733cb66b9a5} + +To signal that a SOF is occurred. + diff --git a/internals_udi_hid_group.md b/internals_udi_hid_group.md new file mode 100644 index 00000000000..3eef9e6128f --- /dev/null +++ b/internals_udi_hid_group.md @@ -0,0 +1,28 @@ +# group `udi_hid_group` {#group__udi__hid__group} + +Common library for all Human Interface Device ([HID](.build/docs/internals_undefined.md#class_h_i_d)) implementation. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public bool `[`udi_hid_setup`](#group__udi__hid__group_1ga9594c21fbb713dabebed1c970664680b)`(uint8_t * rate,uint8_t * protocol,uint8_t * report_desc,bool(*)(void) setup_report)` | Decode [HID](.build/docs/internals_undefined.md#class_h_i_d) setup request. + +## Members + +#### `public bool `[`udi_hid_setup`](#group__udi__hid__group_1ga9594c21fbb713dabebed1c970664680b)`(uint8_t * rate,uint8_t * protocol,uint8_t * report_desc,bool(*)(void) setup_report)` {#group__udi__hid__group_1ga9594c21fbb713dabebed1c970664680b} + +Decode [HID](.build/docs/internals_undefined.md#class_h_i_d) setup request. + +#### Parameters +* `rate` Pointer on rate of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `protocol` Pointer on protocol of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `report_desc` Pointer on report descriptor of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `set_report` Pointer on set_report callback of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +#### Returns +`1` if function was successfully done, otherwise `0`. + diff --git a/internals_udi_hid_group_internal.md b/internals_udi_hid_group_internal.md new file mode 100644 index 00000000000..47fec1a6ec0 --- /dev/null +++ b/internals_udi_hid_group_internal.md @@ -0,0 +1,34 @@ +# group `udi_hid_group_internal` {#group__udi__hid__group__internal} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public static bool `[`udi_hid_reqstdifaceget_descriptor`](#group__udi__hid__group__internal_1ga0ecbd5a80812ac07a1ee3f890a959640)`(uint8_t * report_desc)` | Send the specific descriptors requested by SETUP request. +`public bool `[`udi_hid_setup`](#group__udi__hid__group__internal_1ga9594c21fbb713dabebed1c970664680b)`(uint8_t * rate,uint8_t * protocol,uint8_t * report_desc,bool(*)(void) setup_report)` | Decode [HID](.build/docs/internals_undefined.md#class_h_i_d) setup request. + +## Members + +#### `public static bool `[`udi_hid_reqstdifaceget_descriptor`](#group__udi__hid__group__internal_1ga0ecbd5a80812ac07a1ee3f890a959640)`(uint8_t * report_desc)` {#group__udi__hid__group__internal_1ga0ecbd5a80812ac07a1ee3f890a959640} + +Send the specific descriptors requested by SETUP request. + +#### Parameters +* `true` if the descriptor is supported + +#### `public bool `[`udi_hid_setup`](#group__udi__hid__group__internal_1ga9594c21fbb713dabebed1c970664680b)`(uint8_t * rate,uint8_t * protocol,uint8_t * report_desc,bool(*)(void) setup_report)` {#group__udi__hid__group__internal_1ga9594c21fbb713dabebed1c970664680b} + +Decode [HID](.build/docs/internals_undefined.md#class_h_i_d) setup request. + +#### Parameters +* `rate` Pointer on rate of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `protocol` Pointer on protocol of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `report_desc` Pointer on report descriptor of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +* `set_report` Pointer on set_report callback of current [HID](.build/docs/internals_undefined.md#class_h_i_d) interface + +#### Returns +`1` if function was successfully done, otherwise `0`. + diff --git a/internals_udi_hid_keyboard_group_single_desc.md b/internals_udi_hid_keyboard_group_single_desc.md new file mode 100644 index 00000000000..fe835384aa1 --- /dev/null +++ b/internals_udi_hid_keyboard_group_single_desc.md @@ -0,0 +1,11 @@ +# group `udi_hid_keyboard_group_single_desc` {#group__udi__hid__keyboard__group__single__desc} + +The following structures provide the USB device descriptors required for USB Device with a single interface [HID](.build/docs/internals_undefined.md#class_h_i_d) keyboard. + +It is ready to use and do not require more definition. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_usb_atmel_ids_group.md b/internals_usb_atmel_ids_group.md new file mode 100644 index 00000000000..2c324d1c74e --- /dev/null +++ b/internals_usb_atmel_ids_group.md @@ -0,0 +1,9 @@ +# group `usb_atmel_ids_group` {#group__usb__atmel__ids__group} + +This module defines Atmel PID and VIDs constants. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_usb_device_group.md b/internals_usb_device_group.md new file mode 100644 index 00000000000..57848ec9d5d --- /dev/null +++ b/internals_usb_device_group.md @@ -0,0 +1,27 @@ +# group `usb_device_group` {#group__usb__device__group} + +This module includes USB Stack Device implementation. The stack is divided in three parts: + +* USB Device Controller (UDC) provides USB chapter 9 compliance + +* USB Device Interface (UDI) provides USB Class compliance + +* USB Device Driver (UDD) provides USB Driver for each Atmel MCU + +Many USB Device applications can be implemented on Atmel MCU. Atmel provides many application notes for different applications: + +* AVR4900, provides general information about Device Stack + +* AVR4901, explains how to create a new class + +* AVR4902, explains how to create a composite device + +* AVR49xx, all device classes provided in ASF have an application note + +A basic USB knowledge is required to understand the USB Device Class application notes ([HID](.build/docs/internals_undefined.md#class_h_i_d),MS,CDC,PHDC,...). Then, to create an USB device with only one class provided by ASF, refer directly to the application note corresponding to this USB class. The USB Device application note for New Class and Composite is dedicated to advanced USB users. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_usb_device_udd_group.md b/internals_usb_device_udd_group.md new file mode 100644 index 00000000000..4f0b118122b --- /dev/null +++ b/internals_usb_device_udd_group.md @@ -0,0 +1,325 @@ +# group `usb_device_udd_group` {#group__usb__device__udd__group} + +USB low-level driver for USB device mode + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`UDC_REMOTEWAKEUP_LPM_ENABLE`](#group__usb__device__udd__group_1gaad02b98c5c4188ff50fd72c81e6bfa20) | +`define `[`UDC_REMOTEWAKEUP_LPM_DISABLE`](#group__usb__device__udd__group_1gabd679a48d3828303b04b4e56b5e92481) | +`define `[`UDC_SUSPEND_LPM_EVENT`](#group__usb__device__udd__group_1gaad464bdb9c5a422a2f337b6367114db6) | +`define `[`dbg_print`](#group__usb__device__udd__group_1gac0876bf5bac7dfffd0ee0b003cdc76ef) | +`define `[`UDD_ENDPOINT_MAX_TRANS`](#group__usb__device__udd__group_1ga9b73a2cd4488b39038d49d865e03fe0e) | Maximum size of a transfer in multi-packet mode +`public static udd_ep_job_t * `[`udd_ep_get_job`](#group__usb__device__udd__group_1ga44d7180f54df872da50d8d04918fc5c7)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Get the detailed job by endpoint number. +`public static void `[`udd_ep_trans_in_next`](#group__usb__device__udd__group_1ga7cd1ac3f0e6071afa036e27c5bd4d33c)`(void * pointer)` | Endpoint IN process, continue to send packets or zero length packet. +`public static void `[`udd_ep_trans_out_next`](#group__usb__device__udd__group_1ga2c2140346e2f4ef3b07e36d2abf2de5e)`(void * pointer)` | Endpoint OUT process, continue to receive packets or zero length packet. +`public static void `[`udd_ep_transfer_process`](#group__usb__device__udd__group_1gaa3607835799fb01db3d38bcbc87463fb)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | Endpoint Transfer Complete callback function, to do the next transfer depends on the direction(IN or OUT) +`public void `[`udd_ep_abort`](#group__usb__device__udd__group_1gaacd4ece19accac669506b615916efe2f)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Aborts transfer on going on endpoint. +`public bool `[`udd_is_high_speed`](#group__usb__device__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c)`(void)` | Test whether the USB Device Controller is running at high speed or not. +`public uint16_t `[`udd_get_frame_number`](#group__usb__device__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320)`(void)` | Returns the current start of frame number. +`public uint16_t `[`udd_get_micro_frame_number`](#group__usb__device__udd__group_1ga63047eec59b8e8798ca1d3366472d82b)`(void)` | Returns the current micro start of frame number. +`public void `[`udd_ep_free`](#group__usb__device__udd__group_1ga12c064720e08b9151e2a47f79d986c29)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Disables an endpoint. +`public bool `[`udd_ep_alloc`](#group__usb__device__udd__group_1gaf87db391732b278915079b43ce20a4c1)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,uint8_t bmAttributes,uint16_t MaxEndpointSize)` | Configures and enables an endpoint. +`public bool `[`udd_ep_is_halted`](#group__usb__device__udd__group_1ga2d531ac8c1e142185c6ed6eaeb2737c0)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Check if the endpoint *ep* is halted. +`public bool `[`udd_ep_set_halt`](#group__usb__device__udd__group_1ga55dd14b9b00781223e39c2549ffdb61c)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Set the halted state of the endpoint *ep*. +`public bool `[`udd_ep_clear_halt`](#group__usb__device__udd__group_1ga2b89e75674bd590432e9928326d5ef73)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` | Clear the halted state of the endpoint *ep*. +`public bool `[`udd_ep_wait_stall_clear`](#group__usb__device__udd__group_1ga9dde9a9ac41ffc519cc2e2f93308db1c)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,`[`udd_callback_halt_cleared_t`](.build/docs/internals_undefined.md#group__udd__group_1ga70b1655bda30b7d03df637a1bb23bdd5)` callback)` | Registers a callback to call when endpoint halt is cleared. +`public static void `[`udd_ctrl_stall_data`](#group__usb__device__udd__group_1gabf919b71cee71a11e1ea4e64fb9891d1)`(void)` | Control Endpoint stall sending data. +`public bool `[`udd_ep_run`](#group__usb__device__udd__group_1ga3023b640115dd86dc922fcd79f5b8757)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,bool b_shortpacket,uint8_t * buf,iram_size_t buf_size,`[`udd_callback_trans_t`](.build/docs/internals_undefined.md#group__udd__group_1ga4e79edfc4d62b203dbc271e80a624917)` callback)` | Allows to receive or send data on an endpoint. +`public void `[`udd_set_address`](#group__usb__device__udd__group_1ga05da762e0faf9d478e532de40afa71f6)`(uint8_t address)` | Changes the USB address of device. +`public uint8_t `[`udd_getaddress`](#group__usb__device__udd__group_1gaebd36638d482f6df00a8aff006ef2246)`(void)` | Returns the USB address of device. +`public void `[`udd_send_remotewakeup`](#group__usb__device__udd__group_1gac447212e04789282dabee65a23fe2a08)`(void)` | The USB driver sends a resume signal called Upstream Resume. +`public void `[`udd_set_setup_payload`](#group__usb__device__udd__group_1ga017ef5ea7626be258c24d345218976f9)`(uint8_t * payload,uint16_t payload_size)` | Load setup payload. +`public static void `[`udd_ctrl_fetch_ram`](#group__usb__device__udd__group_1gaf6ffb95ec28493ddaf038642ee995ce6)`(void)` | Control Endpoint translate the data in buffer into Device Request Struct. +`public static void `[`udd_ctrl_send_zlp_in`](#group__usb__device__udd__group_1gab6a8abd5db8a94d6becc73b2b70dc748)`(void)` | Control Endpoint send out zero length packet. +`public static void `[`udd_ctrl_in_sent`](#group__usb__device__udd__group_1ga181ffd0cddf5130f55df6df8ca3f916c)`(void)` | Process control endpoint IN transaction. +`public static void `[`udd_ctrl_out_received`](#group__usb__device__udd__group_1gaa137563d9a7717c634279ad596fbc5fb)`(void * pointer)` | Process control endpoint OUT transaction. +`public static void `[`_usb_ep0_on_setup`](#group__usb__device__udd__group_1ga2f36d2d5628b8edfaf619bcb2c7de44f)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`udd_ctrl_underflow`](#group__usb__device__udd__group_1gae49bae7d7d68329b1c050f39c902d08e)`(void * pointer)` | Control Endpoint Process when underflow condition has occurred. +`public static void `[`udd_ctrl_overflow`](#group__usb__device__udd__group_1ga58ec0c5b490824774f753cc9ff6c1250)`(void * pointer)` | Control Endpoint Process when overflow condition has occurred. +`public static void `[`_usb_ep0_on_tansfer_fail`](#group__usb__device__udd__group_1ga67ec9c51a13358e3e241b2d10b3b4a05)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`_usb_ep0_on_tansfer_ok`](#group__usb__device__udd__group_1gabe51608c4f3fb3cb905463758645127c)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`udd_ctrl_ep_enable`](#group__usb__device__udd__group_1ga16a526f9870d3b670345b98bcfbe166c)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst)` | Enable Control Endpoint. +`public static void `[`_usb_on_suspend`](#group__usb__device__udd__group_1gaf4c2f4bf0f76bcf873d165f1e960c8e1)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`_usb_on_sof_notify`](#group__usb__device__udd__group_1gae65a2792570d8aec7e758b3526721086)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`_usb_on_bus_reset`](#group__usb__device__udd__group_1gaf286144a1b50b68ed2edd38d67e1f4b0)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public static void `[`_usb_on_wakeup`](#group__usb__device__udd__group_1ga563d04cd60d478a430261aaa9da5e07a)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` | +`public void `[`udd_detach`](#group__usb__device__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e)`(void)` | Detaches the device from the bus. +`public void `[`udd_attach`](#group__usb__device__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f)`(void)` | Attach device to the bus when possible. +`public void `[`udd_enable`](#group__usb__device__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42)`(void)` | Enables the USB Device mode. +`public void `[`udd_disable`](#group__usb__device__udd__group_1gab283432057b934e9d73ac9282d9b0f11)`(void)` | Disables the USB Device mode. + +## Members + +#### `define `[`UDC_REMOTEWAKEUP_LPM_ENABLE`](#group__usb__device__udd__group_1gaad02b98c5c4188ff50fd72c81e6bfa20) {#group__usb__device__udd__group_1gaad02b98c5c4188ff50fd72c81e6bfa20} + +#### `define `[`UDC_REMOTEWAKEUP_LPM_DISABLE`](#group__usb__device__udd__group_1gabd679a48d3828303b04b4e56b5e92481) {#group__usb__device__udd__group_1gabd679a48d3828303b04b4e56b5e92481} + +#### `define `[`UDC_SUSPEND_LPM_EVENT`](#group__usb__device__udd__group_1gaad464bdb9c5a422a2f337b6367114db6) {#group__usb__device__udd__group_1gaad464bdb9c5a422a2f337b6367114db6} + +#### `define `[`dbg_print`](#group__usb__device__udd__group_1gac0876bf5bac7dfffd0ee0b003cdc76ef) {#group__usb__device__udd__group_1gac0876bf5bac7dfffd0ee0b003cdc76ef} + +#### `define `[`UDD_ENDPOINT_MAX_TRANS`](#group__usb__device__udd__group_1ga9b73a2cd4488b39038d49d865e03fe0e) {#group__usb__device__udd__group_1ga9b73a2cd4488b39038d49d865e03fe0e} + +Maximum size of a transfer in multi-packet mode + +#### `public static udd_ep_job_t * `[`udd_ep_get_job`](#group__usb__device__udd__group_1ga44d7180f54df872da50d8d04918fc5c7)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1ga44d7180f54df872da50d8d04918fc5c7} + +Get the detailed job by endpoint number. + +#### Parameters +* `ep` Endpoint Address + +#### Parameters +* `pointer` to an udd_ep_job_t structure instance + +#### `public static void `[`udd_ep_trans_in_next`](#group__usb__device__udd__group_1ga7cd1ac3f0e6071afa036e27c5bd4d33c)`(void * pointer)` {#group__usb__device__udd__group_1ga7cd1ac3f0e6071afa036e27c5bd4d33c} + +Endpoint IN process, continue to send packets or zero length packet. + +#### Parameters +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public static void `[`udd_ep_trans_out_next`](#group__usb__device__udd__group_1ga2c2140346e2f4ef3b07e36d2abf2de5e)`(void * pointer)` {#group__usb__device__udd__group_1ga2c2140346e2f4ef3b07e36d2abf2de5e} + +Endpoint OUT process, continue to receive packets or zero length packet. + +#### Parameters +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public static void `[`udd_ep_transfer_process`](#group__usb__device__udd__group_1gaa3607835799fb01db3d38bcbc87463fb)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1gaa3607835799fb01db3d38bcbc87463fb} + +Endpoint Transfer Complete callback function, to do the next transfer depends on the direction(IN or OUT) + +#### Parameters +* `module_inst` Pointer to USB module instance + +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public void `[`udd_ep_abort`](#group__usb__device__udd__group_1gaacd4ece19accac669506b615916efe2f)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1gaacd4ece19accac669506b615916efe2f} + +Aborts transfer on going on endpoint. + +If a transfer is on going, then it is stopped and the callback registered is called to signal the end of transfer. Note: The control endpoint is not authorized. + +#### Parameters +* `ep` Endpoint to abort + +#### `public bool `[`udd_is_high_speed`](#group__usb__device__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c)`(void)` {#group__usb__device__udd__group_1ga85f403ddb78776b1ba014dafd3ffec2c} + +Test whether the USB Device Controller is running at high speed or not. + +#### Returns +`true` if the Device is running at high speed mode, otherwise `false`. + +#### `public uint16_t `[`udd_get_frame_number`](#group__usb__device__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320)`(void)` {#group__usb__device__udd__group_1ga96dc248cc05e07ffe2cf21e4d7465320} + +Returns the current start of frame number. + +#### Returns +current start of frame number. + +#### `public uint16_t `[`udd_get_micro_frame_number`](#group__usb__device__udd__group_1ga63047eec59b8e8798ca1d3366472d82b)`(void)` {#group__usb__device__udd__group_1ga63047eec59b8e8798ca1d3366472d82b} + +Returns the current micro start of frame number. + +#### Returns +current micro start of frame number required in high speed mode. + +#### `public void `[`udd_ep_free`](#group__usb__device__udd__group_1ga12c064720e08b9151e2a47f79d986c29)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1ga12c064720e08b9151e2a47f79d986c29} + +Disables an endpoint. + +#### Parameters +* `ep` Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + +#### `public bool `[`udd_ep_alloc`](#group__usb__device__udd__group_1gaf87db391732b278915079b43ce20a4c1)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,uint8_t bmAttributes,uint16_t MaxEndpointSize)` {#group__usb__device__udd__group_1gaf87db391732b278915079b43ce20a4c1} + +Configures and enables an endpoint. + +#### Parameters +* `ep` Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + +* `bmAttributes` Attributes of endpoint declared in the descriptor. + +* `MaxEndpointSize` Endpoint maximum size + +#### Returns +`1` if the endpoint is enabled, otherwise `0`. + +#### `public bool `[`udd_ep_is_halted`](#group__usb__device__udd__group_1ga2d531ac8c1e142185c6ed6eaeb2737c0)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1ga2d531ac8c1e142185c6ed6eaeb2737c0} + +Check if the endpoint *ep* is halted. + +#### Parameters +* `ep` The ID of the endpoint to check. + +#### Returns +`1` if *ep* is halted, otherwise `0`. + +#### `public bool `[`udd_ep_set_halt`](#group__usb__device__udd__group_1ga55dd14b9b00781223e39c2549ffdb61c)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1ga55dd14b9b00781223e39c2549ffdb61c} + +Set the halted state of the endpoint *ep*. + +After calling this function, any transaction on *ep* will result in a STALL handshake being sent. Any pending transactions will be performed first, however. + +#### Parameters +* `ep` The ID of the endpoint to be halted + +#### Returns +`1` if *ep* is halted, otherwise `0`. + +#### `public bool `[`udd_ep_clear_halt`](#group__usb__device__udd__group_1ga2b89e75674bd590432e9928326d5ef73)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep)` {#group__usb__device__udd__group_1ga2b89e75674bd590432e9928326d5ef73} + +Clear the halted state of the endpoint *ep*. + +After calling this function, any transaction on *ep* will be handled normally, i.e. a STALL handshake will not be sent, and the data toggle sequence will start at DATA0. + +#### Parameters +* `ep` The ID of the endpoint to be un-halted + +#### Returns +`1` if function was successfully done, otherwise `0`. + +#### `public bool `[`udd_ep_wait_stall_clear`](#group__usb__device__udd__group_1ga9dde9a9ac41ffc519cc2e2f93308db1c)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,`[`udd_callback_halt_cleared_t`](.build/docs/internals_undefined.md#group__udd__group_1ga70b1655bda30b7d03df637a1bb23bdd5)` callback)` {#group__usb__device__udd__group_1ga9dde9a9ac41ffc519cc2e2f93308db1c} + +Registers a callback to call when endpoint halt is cleared. + +#### Parameters +* `ep` The ID of the endpoint to use + +* `callback` NULL or function to call when endpoint halt is cleared + +if the endpoint is not halted then the *callback* is called immediately. + +#### Returns +`1` if the register is accepted, otherwise `0`. + +#### `public static void `[`udd_ctrl_stall_data`](#group__usb__device__udd__group_1gabf919b71cee71a11e1ea4e64fb9891d1)`(void)` {#group__usb__device__udd__group_1gabf919b71cee71a11e1ea4e64fb9891d1} + +Control Endpoint stall sending data. + +#### `public bool `[`udd_ep_run`](#group__usb__device__udd__group_1ga3023b640115dd86dc922fcd79f5b8757)`(`[`udd_ep_id_t`](.build/docs/internals_undefined.md#group__udd__group_1ga6f25ea016c07bd48c3074f51d8ef8b01)` ep,bool b_shortpacket,uint8_t * buf,iram_size_t buf_size,`[`udd_callback_trans_t`](.build/docs/internals_undefined.md#group__udd__group_1ga4e79edfc4d62b203dbc271e80a624917)` callback)` {#group__usb__device__udd__group_1ga3023b640115dd86dc922fcd79f5b8757} + +Allows to receive or send data on an endpoint. + +The driver uses a specific DMA USB to transfer data from internal RAM to endpoint, if this one is available. When the transfer is finished or aborted (stall, reset, ...), the *callback* is called. The *callback* returns the transfer status and eventually the number of byte transfered. Note: The control endpoint is not authorized. + +#### Parameters +* `ep` The ID of the endpoint to use + +* `b_shortpacket` Enabled automatic short packet + +* `buf` Buffer on Internal RAM to send or fill. It must be align, then use COMPILER_WORD_ALIGNED. + +* `buf_size` Buffer size to send or fill + +* `callback` NULL or function to call at the end of transfer + +About *b_shortpacket*, for IN endpoint it means that a short packet (or a Zero Length Packet) will be sent to the USB line to properly close the usb transfer at the end of the data transfer. For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer at the end of the data transfer (received short packet). + +#### Returns +`1` if function was successfully done, otherwise `0`. + +#### `public void `[`udd_set_address`](#group__usb__device__udd__group_1ga05da762e0faf9d478e532de40afa71f6)`(uint8_t address)` {#group__usb__device__udd__group_1ga05da762e0faf9d478e532de40afa71f6} + +Changes the USB address of device. + +#### Parameters +* `address` New USB address + +#### `public uint8_t `[`udd_getaddress`](#group__usb__device__udd__group_1gaebd36638d482f6df00a8aff006ef2246)`(void)` {#group__usb__device__udd__group_1gaebd36638d482f6df00a8aff006ef2246} + +Returns the USB address of device. + +#### Returns +USB address + +#### `public void `[`udd_send_remotewakeup`](#group__usb__device__udd__group_1gac447212e04789282dabee65a23fe2a08)`(void)` {#group__usb__device__udd__group_1gac447212e04789282dabee65a23fe2a08} + +The USB driver sends a resume signal called Upstream Resume. + +#### `public void `[`udd_set_setup_payload`](#group__usb__device__udd__group_1ga017ef5ea7626be258c24d345218976f9)`(uint8_t * payload,uint16_t payload_size)` {#group__usb__device__udd__group_1ga017ef5ea7626be258c24d345218976f9} + +Load setup payload. + +#### Parameters +* `payload` Pointer on payload + +* `payload_size` Size of payload + +#### `public static void `[`udd_ctrl_fetch_ram`](#group__usb__device__udd__group_1gaf6ffb95ec28493ddaf038642ee995ce6)`(void)` {#group__usb__device__udd__group_1gaf6ffb95ec28493ddaf038642ee995ce6} + +Control Endpoint translate the data in buffer into Device Request Struct. + +#### `public static void `[`udd_ctrl_send_zlp_in`](#group__usb__device__udd__group_1gab6a8abd5db8a94d6becc73b2b70dc748)`(void)` {#group__usb__device__udd__group_1gab6a8abd5db8a94d6becc73b2b70dc748} + +Control Endpoint send out zero length packet. + +#### `public static void `[`udd_ctrl_in_sent`](#group__usb__device__udd__group_1ga181ffd0cddf5130f55df6df8ca3f916c)`(void)` {#group__usb__device__udd__group_1ga181ffd0cddf5130f55df6df8ca3f916c} + +Process control endpoint IN transaction. + +#### `public static void `[`udd_ctrl_out_received`](#group__usb__device__udd__group_1gaa137563d9a7717c634279ad596fbc5fb)`(void * pointer)` {#group__usb__device__udd__group_1gaa137563d9a7717c634279ad596fbc5fb} + +Process control endpoint OUT transaction. + +#### Parameters +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public static void `[`_usb_ep0_on_setup`](#group__usb__device__udd__group_1ga2f36d2d5628b8edfaf619bcb2c7de44f)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1ga2f36d2d5628b8edfaf619bcb2c7de44f} + +#### `public static void `[`udd_ctrl_underflow`](#group__usb__device__udd__group_1gae49bae7d7d68329b1c050f39c902d08e)`(void * pointer)` {#group__usb__device__udd__group_1gae49bae7d7d68329b1c050f39c902d08e} + +Control Endpoint Process when underflow condition has occurred. + +#### Parameters +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public static void `[`udd_ctrl_overflow`](#group__usb__device__udd__group_1ga58ec0c5b490824774f753cc9ff6c1250)`(void * pointer)` {#group__usb__device__udd__group_1ga58ec0c5b490824774f753cc9ff6c1250} + +Control Endpoint Process when overflow condition has occurred. + +#### Parameters +* `pointer` Pointer to the endpoint transfer status parameter struct from driver layer. + +#### `public static void `[`_usb_ep0_on_tansfer_fail`](#group__usb__device__udd__group_1ga67ec9c51a13358e3e241b2d10b3b4a05)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1ga67ec9c51a13358e3e241b2d10b3b4a05} + +#### `public static void `[`_usb_ep0_on_tansfer_ok`](#group__usb__device__udd__group_1gabe51608c4f3fb3cb905463758645127c)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1gabe51608c4f3fb3cb905463758645127c} + +#### `public static void `[`udd_ctrl_ep_enable`](#group__usb__device__udd__group_1ga16a526f9870d3b670345b98bcfbe166c)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst)` {#group__usb__device__udd__group_1ga16a526f9870d3b670345b98bcfbe166c} + +Enable Control Endpoint. + +#### Parameters +* `module_inst` Pointer to USB module instance + +#### `public static void `[`_usb_on_suspend`](#group__usb__device__udd__group_1gaf4c2f4bf0f76bcf873d165f1e960c8e1)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1gaf4c2f4bf0f76bcf873d165f1e960c8e1} + +#### `public static void `[`_usb_on_sof_notify`](#group__usb__device__udd__group_1gae65a2792570d8aec7e758b3526721086)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1gae65a2792570d8aec7e758b3526721086} + +#### `public static void `[`_usb_on_bus_reset`](#group__usb__device__udd__group_1gaf286144a1b50b68ed2edd38d67e1f4b0)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1gaf286144a1b50b68ed2edd38d67e1f4b0} + +#### `public static void `[`_usb_on_wakeup`](#group__usb__device__udd__group_1ga563d04cd60d478a430261aaa9da5e07a)`(struct `[`usb_module`](.build/docs/internals_undefined.md#structusb__module)` * module_inst,void * pointer)` {#group__usb__device__udd__group_1ga563d04cd60d478a430261aaa9da5e07a} + +#### `public void `[`udd_detach`](#group__usb__device__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e)`(void)` {#group__usb__device__udd__group_1ga03e59eaa264f1dbe5a52559311d0520e} + +Detaches the device from the bus. + +The driver must remove pull-up on USB line D- or D+. + +#### `public void `[`udd_attach`](#group__usb__device__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f)`(void)` {#group__usb__device__udd__group_1ga7a7c0d9236c922c2af33c6702565a99f} + +Attach device to the bus when possible. + +If a VBus control is included in driver, then it will attach device when an acceptable Vbus level from the host is detected. + +#### `public void `[`udd_enable`](#group__usb__device__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42)`(void)` {#group__usb__device__udd__group_1ga9792d1899ae058e3984d6a622fe2ad42} + +Enables the USB Device mode. + +#### `public void `[`udd_disable`](#group__usb__device__udd__group_1gab283432057b934e9d73ac9282d9b0f11)`(void)` {#group__usb__device__udd__group_1gab283432057b934e9d73ac9282d9b0f11} + +Disables the USB Device mode. + diff --git a/internals_usb_group.md b/internals_usb_group.md new file mode 100644 index 00000000000..172671fd5dd --- /dev/null +++ b/internals_usb_group.md @@ -0,0 +1,9 @@ +# group `usb_group` {#group__usb__group} + +This stack includes the USB Device Stack, USB Host Stack and common definitions. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- + diff --git a/internals_usb_hid_protocol.md b/internals_usb_hid_protocol.md new file mode 100644 index 00000000000..5eb7b012dc9 --- /dev/null +++ b/internals_usb_hid_protocol.md @@ -0,0 +1,118 @@ +# group `usb_hid_protocol` {#group__usb__hid__protocol} + +USB Human Interface Device ([HID](.build/docs/internals_undefined.md#class_h_i_d)) protocol definitions. + +protocol definitions + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`enum `[`usb_reqid_hid`](#group__usb__hid__protocol_1gaa7c41bb1274630413fb8f1e9a8acb3e5) | Hid USB requests (bRequest) +`enum `[`usb_descriptor_type_hid`](#group__usb__hid__protocol_1ga75d07fddd98e94eee499e34ce80eebc7) | [HID](.build/docs/internals_undefined.md#class_h_i_d) USB descriptor types. +`enum `[`usb_hid_item_report_type`](#group__usb__hid__protocol_1gab8c213eaa38f71a4aae0c2bb7341f170) | [HID](.build/docs/internals_undefined.md#class_h_i_d) Type for report descriptor. +`enum `[`usb_hid_report_type`](#group__usb__hid__protocol_1ga5832b449d0ccdae41b51ee5436e8df28) | [HID](.build/docs/internals_undefined.md#class_h_i_d) report type. +`enum `[`usb_hid_protocol`](#group__usb__hid__protocol_1gaf68d2167c72cb42e4788cbeba994c255) | [HID](.build/docs/internals_undefined.md#class_h_i_d) protocol. +`struct `[`usb_hid_descriptor_t`](#structusb__hid__descriptor__t) | [HID](.build/docs/internals_undefined.md#class_h_i_d) Descriptor. + +## Members + +#### `enum `[`usb_reqid_hid`](#group__usb__hid__protocol_1gaa7c41bb1274630413fb8f1e9a8acb3e5) {#group__usb__hid__protocol_1gaa7c41bb1274630413fb8f1e9a8acb3e5} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_REQ_HID_GET_REPORT | +USB_REQ_HID_GET_IDLE | +USB_REQ_HID_GET_PROTOCOL | +USB_REQ_HID_SET_REPORT | +USB_REQ_HID_SET_IDLE | +USB_REQ_HID_SET_PROTOCOL | + +Hid USB requests (bRequest) + +#### `enum `[`usb_descriptor_type_hid`](#group__usb__hid__protocol_1ga75d07fddd98e94eee499e34ce80eebc7) {#group__usb__hid__protocol_1ga75d07fddd98e94eee499e34ce80eebc7} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DT_HID | +USB_DT_HID_REPORT | +USB_DT_HID_PHYSICAL | + +[HID](.build/docs/internals_undefined.md#class_h_i_d) USB descriptor types. + +#### `enum `[`usb_hid_item_report_type`](#group__usb__hid__protocol_1gab8c213eaa38f71a4aae0c2bb7341f170) {#group__usb__hid__protocol_1gab8c213eaa38f71a4aae0c2bb7341f170} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_HID_ITEM_REPORT_TYPE_MAIN | +USB_HID_ITEM_REPORT_TYPE_GLOBAL | +USB_HID_ITEM_REPORT_TYPE_LOCAL | +USB_HID_ITEM_REPORT_TYPE_LONG | + +[HID](.build/docs/internals_undefined.md#class_h_i_d) Type for report descriptor. + +#### `enum `[`usb_hid_report_type`](#group__usb__hid__protocol_1ga5832b449d0ccdae41b51ee5436e8df28) {#group__usb__hid__protocol_1ga5832b449d0ccdae41b51ee5436e8df28} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_HID_REPORT_TYPE_INPUT | +USB_HID_REPORT_TYPE_OUTPUT | +USB_HID_REPORT_TYPE_FEATURE | + +[HID](.build/docs/internals_undefined.md#class_h_i_d) report type. + +#### `enum `[`usb_hid_protocol`](#group__usb__hid__protocol_1gaf68d2167c72cb42e4788cbeba994c255) {#group__usb__hid__protocol_1gaf68d2167c72cb42e4788cbeba994c255} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_HID_PROCOTOL_BOOT | +USB_HID_PROCOTOL_REPORT | + +[HID](.build/docs/internals_undefined.md#class_h_i_d) protocol. + +# struct `usb_hid_descriptor_t` {#structusb__hid__descriptor__t} + +[HID](.build/docs/internals_undefined.md#class_h_i_d) Descriptor. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__hid__descriptor__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | Size of this descriptor in bytes. +`public uint8_t `[`bDescriptorType`](#structusb__hid__descriptor__t_1a67d7027b9eb9ed268d28e84fbc675707) | [HID](.build/docs/internals_undefined.md#class_h_i_d) descriptor type. +`public le16_t `[`bcdHID`](#structusb__hid__descriptor__t_1ab86c23448d45c6d68efec9f9af5d10de) | Binary Coded Decimal Spec. release. +`public uint8_t `[`bCountryCode`](#structusb__hid__descriptor__t_1a969a604033b72573d59a740badf6920e) | Hardware target country. +`public uint8_t `[`bNumDescriptors`](#structusb__hid__descriptor__t_1a86ff434026085d9c0c751185eb3700c5) | Number of [HID](.build/docs/internals_undefined.md#class_h_i_d) class descriptors to follow. +`public uint8_t `[`bRDescriptorType`](#structusb__hid__descriptor__t_1a6da89ed91bee6e0a4f2c8cf3b40a7ede) | Report descriptor type. +`public le16_t `[`wDescriptorLength`](#structusb__hid__descriptor__t_1ab3d5c878a0abf618eecc7f860e9aeb62) | Total length of Report descriptor. + +## Members + +#### `public uint8_t `[`bLength`](#structusb__hid__descriptor__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__hid__descriptor__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +Size of this descriptor in bytes. + +#### `public uint8_t `[`bDescriptorType`](#structusb__hid__descriptor__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__hid__descriptor__t_1a67d7027b9eb9ed268d28e84fbc675707} + +[HID](.build/docs/internals_undefined.md#class_h_i_d) descriptor type. + +#### `public le16_t `[`bcdHID`](#structusb__hid__descriptor__t_1ab86c23448d45c6d68efec9f9af5d10de) {#structusb__hid__descriptor__t_1ab86c23448d45c6d68efec9f9af5d10de} + +Binary Coded Decimal Spec. release. + +#### `public uint8_t `[`bCountryCode`](#structusb__hid__descriptor__t_1a969a604033b72573d59a740badf6920e) {#structusb__hid__descriptor__t_1a969a604033b72573d59a740badf6920e} + +Hardware target country. + +#### `public uint8_t `[`bNumDescriptors`](#structusb__hid__descriptor__t_1a86ff434026085d9c0c751185eb3700c5) {#structusb__hid__descriptor__t_1a86ff434026085d9c0c751185eb3700c5} + +Number of [HID](.build/docs/internals_undefined.md#class_h_i_d) class descriptors to follow. + +#### `public uint8_t `[`bRDescriptorType`](#structusb__hid__descriptor__t_1a6da89ed91bee6e0a4f2c8cf3b40a7ede) {#structusb__hid__descriptor__t_1a6da89ed91bee6e0a4f2c8cf3b40a7ede} + +Report descriptor type. + +#### `public le16_t `[`wDescriptorLength`](#structusb__hid__descriptor__t_1ab3d5c878a0abf618eecc7f860e9aeb62) {#structusb__hid__descriptor__t_1ab3d5c878a0abf618eecc7f860e9aeb62} + +Total length of Report descriptor. + diff --git a/internals_usb_protocol_group.md b/internals_usb_protocol_group.md new file mode 100644 index 00000000000..fe141d5f8da --- /dev/null +++ b/internals_usb_protocol_group.md @@ -0,0 +1,806 @@ +# group `usb_protocol_group` {#group__usb__protocol__group} + +This module defines constants and data structures provided by the USB 2.0 specification. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`define `[`USB_V2_0`](#group__usb__protocol__group_1ga9bccec980a4f41a481b389b4f0c9c690) | Value for field bcdUSB. +`define `[`USB_V2_1`](#group__usb__protocol__group_1ga98059f51cd65930412083d423a70dd17) | USB Specification version 2.01. +`define `[`USB_REQ_DIR_OUT`](#group__usb__protocol__group_1ga3fae7189eea003bf79ac2949b0f50584) | USB request data transfer direction (bmRequestType) +`define `[`USB_REQ_DIR_IN`](#group__usb__protocol__group_1ga3d3c24265f68a720887ae4ff7158d605) | Device to host. +`define `[`USB_REQ_DIR_MASK`](#group__usb__protocol__group_1gac94f5ec9106e17f2e6d927eeac3d530f) | Mask. +`define `[`USB_REQ_TYPE_STANDARD`](#group__usb__protocol__group_1ga3eb781776ab6dcbc6fa96e1b0ed18011) | USB request types (bmRequestType) +`define `[`USB_REQ_TYPE_CLASS`](#group__usb__protocol__group_1gaff9ee0044c6cb131b2908356adc37dff) | Class-specific request. +`define `[`USB_REQ_TYPE_VENDOR`](#group__usb__protocol__group_1ga71855621792f72443ed5497b313a2517) | Vendor-specific request. +`define `[`USB_REQ_TYPE_MASK`](#group__usb__protocol__group_1ga8be8332e2da1e54c74c5f2a2230b0a28) | Mask. +`define `[`USB_REQ_RECIP_DEVICE`](#group__usb__protocol__group_1ga65c1569b970837dd4a2ad8e1b4097589) | USB recipient codes (bmRequestType) +`define `[`USB_REQ_RECIP_INTERFACE`](#group__usb__protocol__group_1gad3d0e7d70c610967cc2ee12c5298ac69) | Recipient interface. +`define `[`USB_REQ_RECIP_ENDPOINT`](#group__usb__protocol__group_1ga1be00350ff83d022d41b4eae81f1e2b2) | Recipient endpoint. +`define `[`USB_REQ_RECIP_OTHER`](#group__usb__protocol__group_1gabb5706061604f770d2ce1f3891ab0296) | Recipient other. +`define `[`USB_REQ_RECIP_MASK`](#group__usb__protocol__group_1gab1738c19d49fe1d4c7edccff90e9e9e4) | Mask. +`define `[`HIRD_50_US`](#group__usb__protocol__group_1ga63ce14c89bdb5349988cb983b7176740) | +`define `[`HIRD_125_US`](#group__usb__protocol__group_1ga8fa50bfccd00843cd32719521720f7f6) | +`define `[`HIRD_200_US`](#group__usb__protocol__group_1gad6f9ff2585cbc2b0ca161ee12a11b154) | +`define `[`HIRD_275_US`](#group__usb__protocol__group_1ga51c55e5d7938a80a53084b5a2a93b9b3) | +`define `[`HIRD_350_US`](#group__usb__protocol__group_1ga28a9220cf691f45fa880638ad92ed95a) | +`define `[`HIRD_425_US`](#group__usb__protocol__group_1gab0f175ff5b6a35c08d4730f3b82e3290) | +`define `[`HIRD_500_US`](#group__usb__protocol__group_1gaf75c36a22358dbe9d27fa2122d39ac32) | +`define `[`HIRD_575_US`](#group__usb__protocol__group_1ga27244f075c4ae2c34bcdeecca8921e9d) | +`define `[`HIRD_650_US`](#group__usb__protocol__group_1ga33e1236c9694d97c574677ed36da8ce4) | +`define `[`HIRD_725_US`](#group__usb__protocol__group_1gab1cfbd6207cc526b33a65593379f1802) | +`define `[`HIRD_800_US`](#group__usb__protocol__group_1gaec9c3475ae7a1a2deefdb7f844ab25b4) | +`define `[`HIRD_875_US`](#group__usb__protocol__group_1ga39eaf9efa2c721560ae7e6d4463ed353) | +`define `[`HIRD_950_US`](#group__usb__protocol__group_1ga6a950e4e5666cd014db36bd4971ac888) | +`define `[`HIRD_1025_US`](#group__usb__protocol__group_1ga07cfb9848da18f98190ff86ca5349b53) | +`define `[`HIRD_1100_US`](#group__usb__protocol__group_1ga52b2c19a0df1c72ed04a97ccb3b9152e) | +`define `[`HIRD_1175_US`](#group__usb__protocol__group_1ga29284c56fb4827b69c00332b7a4fdb76) | +`define `[`USB_LPM_ATTRIBUT_BLINKSTATE_MASK`](#group__usb__protocol__group_1gaf39d50c3bb01f68fa434e7fdf3a44e22) | Fields definition from a LPM TOKEN +`define `[`USB_LPM_ATTRIBUT_FIRD_MASK`](#group__usb__protocol__group_1gaf53a7676592b02f9bb846e1062af463c) | +`define `[`USB_LPM_ATTRIBUT_REMOTEWAKE_MASK`](#group__usb__protocol__group_1ga9c1618c348394534d968097c8d76c092) | +`define `[`USB_LPM_ATTRIBUT_BLINKSTATE`](#group__usb__protocol__group_1ga1deb3dda1fc39b7425359c72eb548b0d) | +`define `[`USB_LPM_ATTRIBUT_FIRD`](#group__usb__protocol__group_1ga0eb84fe948d5e4650a39d6081b959c70) | +`define `[`USB_LPM_ATTRIBUT_REMOTEWAKE`](#group__usb__protocol__group_1ga7482138e5ce2d2ec9482bcd5dbd9bd64) | +`define `[`USB_LPM_ATTRIBUT_BLINKSTATE_L1`](#group__usb__protocol__group_1ga02be6765d15e86d37fd66ce6862a16fc) | +`define `[`USB_EP_ADDR_MASK`](#group__usb__protocol__group_1ga0316d8f43a1648b76df257332b26aeb9) | Mask selecting the index part of an endpoint address. +`define `[`USB_EP_DIR_IN`](#group__usb__protocol__group_1gaae8411e95f26738326bc25a0161dde99) | Endpoint transfer direction is IN. +`define `[`USB_EP_DIR_OUT`](#group__usb__protocol__group_1ga0510b0a04d9cef144e4d9793310abccf) | Endpoint transfer direction is OUT. +`define `[`USB_MAX_DESC_LEN`](#group__usb__protocol__group_1ga27dacd4e0b04d4ef7b8aadf6ea886f3c) | Maximum length in bytes of a USB descriptor. +`define `[`USB_CONFIG_ATTR_MUST_SET`](#group__usb__protocol__group_1gac7063e965def0eaeb4d45a6f9048dc53) | Must always be set. +`define `[`USB_CONFIG_ATTR_BUS_POWERED`](#group__usb__protocol__group_1ga10945c8d92454009444979c38b9d2cca) | Bus-powered. +`define `[`USB_CONFIG_ATTR_SELF_POWERED`](#group__usb__protocol__group_1gaf1b445db8c331630bbedb383544ed80b) | Self-powered. +`define `[`USB_CONFIG_ATTR_REMOTE_WAKEUP`](#group__usb__protocol__group_1gab8f513d1888f75d8e18960e1b1f3f747) | remote wakeup supported +`define `[`USB_CONFIG_MAX_POWER`](#group__usb__protocol__group_1ga55d9db758a4f408eebf4b26c6001ac9b) | Max power in mA. +`enum `[`usb_reqid`](#group__usb__protocol__group_1gab43332ff8dbad3dd3c8c882b1bd68a89) | Standard USB requests (bRequest) +`enum `[`usb_device_status`](#group__usb__protocol__group_1ga5c6f61a70ef0fda1a1d6f9a34f2f0f1c) | Standard USB device status flags. +`enum `[`usb_interface_status`](#group__usb__protocol__group_1ga61c6d9f1bcc6112f394333fac658d627) | Standard USB Interface status flags. +`enum `[`usb_endpoint_status`](#group__usb__protocol__group_1gaf926ff975fcda57f214001b51f15092d) | Standard USB endpoint status flags. +`enum `[`usb_device_feature`](#group__usb__protocol__group_1gab9975b89ad7079085d0300eab037c3ac) | Standard USB device feature flags. +`enum `[`usb_device_hs_test_mode`](#group__usb__protocol__group_1ga9027bb283d3666e351fe5c403292cf2e) | Test Mode possible on HS USB device. +`enum `[`usb_endpoint_feature`](#group__usb__protocol__group_1gac46bc23132eb03cefa56ba47024ced5d) | Standard USB endpoint feature/status flags. +`enum `[`usb_test_mode_selector`](#group__usb__protocol__group_1gade3fc5b71e88ed167a8c8d67ee087db3) | Standard USB Test Mode Selectors. +`enum `[`usb_descriptor_type`](#group__usb__protocol__group_1ga87d46dd117d939964c939f1518dec93f) | Standard USB descriptor types. +`enum `[`usb_capability_type`](#group__usb__protocol__group_1gab4eef94a7d2be2570193c4f9400a6fa6) | USB Device Capability types. +`enum `[`usb_capability_extension_attr`](#group__usb__protocol__group_1ga4fa8bfac1cf05037ee2ef05aaa190299) | USB Device Capability - USB 2.0 Extension To fill bmAttributes field of usb_capa_ext_desc_t structure. +`enum `[`usb_ep_type`](#group__usb__protocol__group_1ga666def795a15032e5bf93a450f79113f) | Standard USB endpoint transfer types. +`enum `[`usb_langid`](#group__usb__protocol__group_1ga1f92deaf695c06566999f0c5343978c1) | Standard USB language IDs for string descriptors. +`struct `[`usb_setup_req_t`](#structusb__setup__req__t) | A USB Device SETUP request. +`struct `[`usb_dev_desc_t`](#structusb__dev__desc__t) | Standard USB device descriptor structure. +`struct `[`usb_dev_qual_desc_t`](#structusb__dev__qual__desc__t) | Standard USB device qualifier descriptor structure. +`struct `[`usb_dev_bos_desc_t`](#structusb__dev__bos__desc__t) | USB Device BOS descriptor structure. +`struct `[`usb_dev_capa_ext_desc_t`](#structusb__dev__capa__ext__desc__t) | USB Device Capabilities - USB 2.0 Extension Descriptor structure. +`struct `[`usb_dev_lpm_desc_t`](#structusb__dev__lpm__desc__t) | USB Device LPM Descriptor structure. +`struct `[`usb_association_desc_t`](#structusb__association__desc__t) | Standard USB Interface Association Descriptor structure. +`struct `[`usb_conf_desc_t`](#structusb__conf__desc__t) | Standard USB configuration descriptor structure. +`struct `[`usb_iad_desc_t`](#structusb__iad__desc__t) | Standard USB association descriptor structure. +`struct `[`usb_iface_desc_t`](#structusb__iface__desc__t) | Standard USB interface descriptor structure. +`struct `[`usb_ep_desc_t`](#structusb__ep__desc__t) | Standard USB endpoint descriptor structure. +`struct `[`usb_str_desc_t`](#structusb__str__desc__t) | A standard USB string descriptor structure. +`struct `[`usb_str_lgid_desc_t`](#structusb__str__lgid__desc__t) | + +## Members + +#### `define `[`USB_V2_0`](#group__usb__protocol__group_1ga9bccec980a4f41a481b389b4f0c9c690) {#group__usb__protocol__group_1ga9bccec980a4f41a481b389b4f0c9c690} + +Value for field bcdUSB. + +USB Specification version 2.00 + +#### `define `[`USB_V2_1`](#group__usb__protocol__group_1ga98059f51cd65930412083d423a70dd17) {#group__usb__protocol__group_1ga98059f51cd65930412083d423a70dd17} + +USB Specification version 2.01. + +#### `define `[`USB_REQ_DIR_OUT`](#group__usb__protocol__group_1ga3fae7189eea003bf79ac2949b0f50584) {#group__usb__protocol__group_1ga3fae7189eea003bf79ac2949b0f50584} + +USB request data transfer direction (bmRequestType) + +Host to device + +#### `define `[`USB_REQ_DIR_IN`](#group__usb__protocol__group_1ga3d3c24265f68a720887ae4ff7158d605) {#group__usb__protocol__group_1ga3d3c24265f68a720887ae4ff7158d605} + +Device to host. + +#### `define `[`USB_REQ_DIR_MASK`](#group__usb__protocol__group_1gac94f5ec9106e17f2e6d927eeac3d530f) {#group__usb__protocol__group_1gac94f5ec9106e17f2e6d927eeac3d530f} + +Mask. + +#### `define `[`USB_REQ_TYPE_STANDARD`](#group__usb__protocol__group_1ga3eb781776ab6dcbc6fa96e1b0ed18011) {#group__usb__protocol__group_1ga3eb781776ab6dcbc6fa96e1b0ed18011} + +USB request types (bmRequestType) + +Standard request + +#### `define `[`USB_REQ_TYPE_CLASS`](#group__usb__protocol__group_1gaff9ee0044c6cb131b2908356adc37dff) {#group__usb__protocol__group_1gaff9ee0044c6cb131b2908356adc37dff} + +Class-specific request. + +#### `define `[`USB_REQ_TYPE_VENDOR`](#group__usb__protocol__group_1ga71855621792f72443ed5497b313a2517) {#group__usb__protocol__group_1ga71855621792f72443ed5497b313a2517} + +Vendor-specific request. + +#### `define `[`USB_REQ_TYPE_MASK`](#group__usb__protocol__group_1ga8be8332e2da1e54c74c5f2a2230b0a28) {#group__usb__protocol__group_1ga8be8332e2da1e54c74c5f2a2230b0a28} + +Mask. + +#### `define `[`USB_REQ_RECIP_DEVICE`](#group__usb__protocol__group_1ga65c1569b970837dd4a2ad8e1b4097589) {#group__usb__protocol__group_1ga65c1569b970837dd4a2ad8e1b4097589} + +USB recipient codes (bmRequestType) + +Recipient device + +#### `define `[`USB_REQ_RECIP_INTERFACE`](#group__usb__protocol__group_1gad3d0e7d70c610967cc2ee12c5298ac69) {#group__usb__protocol__group_1gad3d0e7d70c610967cc2ee12c5298ac69} + +Recipient interface. + +#### `define `[`USB_REQ_RECIP_ENDPOINT`](#group__usb__protocol__group_1ga1be00350ff83d022d41b4eae81f1e2b2) {#group__usb__protocol__group_1ga1be00350ff83d022d41b4eae81f1e2b2} + +Recipient endpoint. + +#### `define `[`USB_REQ_RECIP_OTHER`](#group__usb__protocol__group_1gabb5706061604f770d2ce1f3891ab0296) {#group__usb__protocol__group_1gabb5706061604f770d2ce1f3891ab0296} + +Recipient other. + +#### `define `[`USB_REQ_RECIP_MASK`](#group__usb__protocol__group_1gab1738c19d49fe1d4c7edccff90e9e9e4) {#group__usb__protocol__group_1gab1738c19d49fe1d4c7edccff90e9e9e4} + +Mask. + +#### `define `[`HIRD_50_US`](#group__usb__protocol__group_1ga63ce14c89bdb5349988cb983b7176740) {#group__usb__protocol__group_1ga63ce14c89bdb5349988cb983b7176740} + +#### `define `[`HIRD_125_US`](#group__usb__protocol__group_1ga8fa50bfccd00843cd32719521720f7f6) {#group__usb__protocol__group_1ga8fa50bfccd00843cd32719521720f7f6} + +#### `define `[`HIRD_200_US`](#group__usb__protocol__group_1gad6f9ff2585cbc2b0ca161ee12a11b154) {#group__usb__protocol__group_1gad6f9ff2585cbc2b0ca161ee12a11b154} + +#### `define `[`HIRD_275_US`](#group__usb__protocol__group_1ga51c55e5d7938a80a53084b5a2a93b9b3) {#group__usb__protocol__group_1ga51c55e5d7938a80a53084b5a2a93b9b3} + +#### `define `[`HIRD_350_US`](#group__usb__protocol__group_1ga28a9220cf691f45fa880638ad92ed95a) {#group__usb__protocol__group_1ga28a9220cf691f45fa880638ad92ed95a} + +#### `define `[`HIRD_425_US`](#group__usb__protocol__group_1gab0f175ff5b6a35c08d4730f3b82e3290) {#group__usb__protocol__group_1gab0f175ff5b6a35c08d4730f3b82e3290} + +#### `define `[`HIRD_500_US`](#group__usb__protocol__group_1gaf75c36a22358dbe9d27fa2122d39ac32) {#group__usb__protocol__group_1gaf75c36a22358dbe9d27fa2122d39ac32} + +#### `define `[`HIRD_575_US`](#group__usb__protocol__group_1ga27244f075c4ae2c34bcdeecca8921e9d) {#group__usb__protocol__group_1ga27244f075c4ae2c34bcdeecca8921e9d} + +#### `define `[`HIRD_650_US`](#group__usb__protocol__group_1ga33e1236c9694d97c574677ed36da8ce4) {#group__usb__protocol__group_1ga33e1236c9694d97c574677ed36da8ce4} + +#### `define `[`HIRD_725_US`](#group__usb__protocol__group_1gab1cfbd6207cc526b33a65593379f1802) {#group__usb__protocol__group_1gab1cfbd6207cc526b33a65593379f1802} + +#### `define `[`HIRD_800_US`](#group__usb__protocol__group_1gaec9c3475ae7a1a2deefdb7f844ab25b4) {#group__usb__protocol__group_1gaec9c3475ae7a1a2deefdb7f844ab25b4} + +#### `define `[`HIRD_875_US`](#group__usb__protocol__group_1ga39eaf9efa2c721560ae7e6d4463ed353) {#group__usb__protocol__group_1ga39eaf9efa2c721560ae7e6d4463ed353} + +#### `define `[`HIRD_950_US`](#group__usb__protocol__group_1ga6a950e4e5666cd014db36bd4971ac888) {#group__usb__protocol__group_1ga6a950e4e5666cd014db36bd4971ac888} + +#### `define `[`HIRD_1025_US`](#group__usb__protocol__group_1ga07cfb9848da18f98190ff86ca5349b53) {#group__usb__protocol__group_1ga07cfb9848da18f98190ff86ca5349b53} + +#### `define `[`HIRD_1100_US`](#group__usb__protocol__group_1ga52b2c19a0df1c72ed04a97ccb3b9152e) {#group__usb__protocol__group_1ga52b2c19a0df1c72ed04a97ccb3b9152e} + +#### `define `[`HIRD_1175_US`](#group__usb__protocol__group_1ga29284c56fb4827b69c00332b7a4fdb76) {#group__usb__protocol__group_1ga29284c56fb4827b69c00332b7a4fdb76} + +#### `define `[`USB_LPM_ATTRIBUT_BLINKSTATE_MASK`](#group__usb__protocol__group_1gaf39d50c3bb01f68fa434e7fdf3a44e22) {#group__usb__protocol__group_1gaf39d50c3bb01f68fa434e7fdf3a44e22} + +Fields definition from a LPM TOKEN + +#### `define `[`USB_LPM_ATTRIBUT_FIRD_MASK`](#group__usb__protocol__group_1gaf53a7676592b02f9bb846e1062af463c) {#group__usb__protocol__group_1gaf53a7676592b02f9bb846e1062af463c} + +#### `define `[`USB_LPM_ATTRIBUT_REMOTEWAKE_MASK`](#group__usb__protocol__group_1ga9c1618c348394534d968097c8d76c092) {#group__usb__protocol__group_1ga9c1618c348394534d968097c8d76c092} + +#### `define `[`USB_LPM_ATTRIBUT_BLINKSTATE`](#group__usb__protocol__group_1ga1deb3dda1fc39b7425359c72eb548b0d) {#group__usb__protocol__group_1ga1deb3dda1fc39b7425359c72eb548b0d} + +#### `define `[`USB_LPM_ATTRIBUT_FIRD`](#group__usb__protocol__group_1ga0eb84fe948d5e4650a39d6081b959c70) {#group__usb__protocol__group_1ga0eb84fe948d5e4650a39d6081b959c70} + +#### `define `[`USB_LPM_ATTRIBUT_REMOTEWAKE`](#group__usb__protocol__group_1ga7482138e5ce2d2ec9482bcd5dbd9bd64) {#group__usb__protocol__group_1ga7482138e5ce2d2ec9482bcd5dbd9bd64} + +#### `define `[`USB_LPM_ATTRIBUT_BLINKSTATE_L1`](#group__usb__protocol__group_1ga02be6765d15e86d37fd66ce6862a16fc) {#group__usb__protocol__group_1ga02be6765d15e86d37fd66ce6862a16fc} + +#### `define `[`USB_EP_ADDR_MASK`](#group__usb__protocol__group_1ga0316d8f43a1648b76df257332b26aeb9) {#group__usb__protocol__group_1ga0316d8f43a1648b76df257332b26aeb9} + +Mask selecting the index part of an endpoint address. + +#### `define `[`USB_EP_DIR_IN`](#group__usb__protocol__group_1gaae8411e95f26738326bc25a0161dde99) {#group__usb__protocol__group_1gaae8411e95f26738326bc25a0161dde99} + +Endpoint transfer direction is IN. + +#### `define `[`USB_EP_DIR_OUT`](#group__usb__protocol__group_1ga0510b0a04d9cef144e4d9793310abccf) {#group__usb__protocol__group_1ga0510b0a04d9cef144e4d9793310abccf} + +Endpoint transfer direction is OUT. + +#### `define `[`USB_MAX_DESC_LEN`](#group__usb__protocol__group_1ga27dacd4e0b04d4ef7b8aadf6ea886f3c) {#group__usb__protocol__group_1ga27dacd4e0b04d4ef7b8aadf6ea886f3c} + +Maximum length in bytes of a USB descriptor. + +The maximum length of a USB descriptor is limited by the 8-bit bLength field. + +#### `define `[`USB_CONFIG_ATTR_MUST_SET`](#group__usb__protocol__group_1gac7063e965def0eaeb4d45a6f9048dc53) {#group__usb__protocol__group_1gac7063e965def0eaeb4d45a6f9048dc53} + +Must always be set. + +#### `define `[`USB_CONFIG_ATTR_BUS_POWERED`](#group__usb__protocol__group_1ga10945c8d92454009444979c38b9d2cca) {#group__usb__protocol__group_1ga10945c8d92454009444979c38b9d2cca} + +Bus-powered. + +#### `define `[`USB_CONFIG_ATTR_SELF_POWERED`](#group__usb__protocol__group_1gaf1b445db8c331630bbedb383544ed80b) {#group__usb__protocol__group_1gaf1b445db8c331630bbedb383544ed80b} + +Self-powered. + +#### `define `[`USB_CONFIG_ATTR_REMOTE_WAKEUP`](#group__usb__protocol__group_1gab8f513d1888f75d8e18960e1b1f3f747) {#group__usb__protocol__group_1gab8f513d1888f75d8e18960e1b1f3f747} + +remote wakeup supported + +#### `define `[`USB_CONFIG_MAX_POWER`](#group__usb__protocol__group_1ga55d9db758a4f408eebf4b26c6001ac9b) {#group__usb__protocol__group_1ga55d9db758a4f408eebf4b26c6001ac9b} + +Max power in mA. + +#### `enum `[`usb_reqid`](#group__usb__protocol__group_1gab43332ff8dbad3dd3c8c882b1bd68a89) {#group__usb__protocol__group_1gab43332ff8dbad3dd3c8c882b1bd68a89} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_REQ_GET_STATUS | +USB_REQ_CLEAR_FEATURE | +USB_REQ_SET_FEATURE | +USB_REQ_SET_ADDRESS | +USB_REQ_GET_DESCRIPTOR | +USB_REQ_SET_DESCRIPTOR | +USB_REQ_GET_CONFIGURATION | +USB_REQ_SET_CONFIGURATION | +USB_REQ_GET_INTERFACE | +USB_REQ_SET_INTERFACE | +USB_REQ_SYNCH_FRAME | + +Standard USB requests (bRequest) + +#### `enum `[`usb_device_status`](#group__usb__protocol__group_1ga5c6f61a70ef0fda1a1d6f9a34f2f0f1c) {#group__usb__protocol__group_1ga5c6f61a70ef0fda1a1d6f9a34f2f0f1c} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DEV_STATUS_BUS_POWERED | +USB_DEV_STATUS_SELF_POWERED | +USB_DEV_STATUS_REMOTEWAKEUP | + +Standard USB device status flags. + +#### `enum `[`usb_interface_status`](#group__usb__protocol__group_1ga61c6d9f1bcc6112f394333fac658d627) {#group__usb__protocol__group_1ga61c6d9f1bcc6112f394333fac658d627} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_IFACE_STATUS_RESERVED | + +Standard USB Interface status flags. + +#### `enum `[`usb_endpoint_status`](#group__usb__protocol__group_1gaf926ff975fcda57f214001b51f15092d) {#group__usb__protocol__group_1gaf926ff975fcda57f214001b51f15092d} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_EP_STATUS_HALTED | + +Standard USB endpoint status flags. + +#### `enum `[`usb_device_feature`](#group__usb__protocol__group_1gab9975b89ad7079085d0300eab037c3ac) {#group__usb__protocol__group_1gab9975b89ad7079085d0300eab037c3ac} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DEV_FEATURE_REMOTE_WAKEUP | Remote wakeup enabled. +USB_DEV_FEATURE_TEST_MODE | USB test mode. +USB_DEV_FEATURE_OTG_B_HNP_ENABLE | +USB_DEV_FEATURE_OTG_A_HNP_SUPPORT | +USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT | + +Standard USB device feature flags. + +valid for SetFeature request. + +#### `enum `[`usb_device_hs_test_mode`](#group__usb__protocol__group_1ga9027bb283d3666e351fe5c403292cf2e) {#group__usb__protocol__group_1ga9027bb283d3666e351fe5c403292cf2e} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DEV_TEST_MODE_J | +USB_DEV_TEST_MODE_K | +USB_DEV_TEST_MODE_SE0_NAK | +USB_DEV_TEST_MODE_PACKET | +USB_DEV_TEST_MODE_FORCE_ENABLE | + +Test Mode possible on HS USB device. + +valid for USB_DEV_FEATURE_TEST_MODE request. + +#### `enum `[`usb_endpoint_feature`](#group__usb__protocol__group_1gac46bc23132eb03cefa56ba47024ced5d) {#group__usb__protocol__group_1gac46bc23132eb03cefa56ba47024ced5d} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_EP_FEATURE_HALT | + +Standard USB endpoint feature/status flags. + +#### `enum `[`usb_test_mode_selector`](#group__usb__protocol__group_1gade3fc5b71e88ed167a8c8d67ee087db3) {#group__usb__protocol__group_1gade3fc5b71e88ed167a8c8d67ee087db3} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_TEST_J | +USB_TEST_K | +USB_TEST_SE0_NAK | +USB_TEST_PACKET | +USB_TEST_FORCE_ENABLE | + +Standard USB Test Mode Selectors. + +#### `enum `[`usb_descriptor_type`](#group__usb__protocol__group_1ga87d46dd117d939964c939f1518dec93f) {#group__usb__protocol__group_1ga87d46dd117d939964c939f1518dec93f} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DT_DEVICE | +USB_DT_CONFIGURATION | +USB_DT_STRING | +USB_DT_INTERFACE | +USB_DT_ENDPOINT | +USB_DT_DEVICE_QUALIFIER | +USB_DT_OTHER_SPEED_CONFIGURATION | +USB_DT_INTERFACE_POWER | +USB_DT_OTG | +USB_DT_IAD | +USB_DT_BOS | +USB_DT_DEVICE_CAPABILITY | + +Standard USB descriptor types. + +#### `enum `[`usb_capability_type`](#group__usb__protocol__group_1gab4eef94a7d2be2570193c4f9400a6fa6) {#group__usb__protocol__group_1gab4eef94a7d2be2570193c4f9400a6fa6} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DC_USB20_EXTENSION | + +USB Device Capability types. + +#### `enum `[`usb_capability_extension_attr`](#group__usb__protocol__group_1ga4fa8bfac1cf05037ee2ef05aaa190299) {#group__usb__protocol__group_1ga4fa8bfac1cf05037ee2ef05aaa190299} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_DC_EXT_LPM | + +USB Device Capability - USB 2.0 Extension To fill bmAttributes field of usb_capa_ext_desc_t structure. + +#### `enum `[`usb_ep_type`](#group__usb__protocol__group_1ga666def795a15032e5bf93a450f79113f) {#group__usb__protocol__group_1ga666def795a15032e5bf93a450f79113f} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_EP_TYPE_CONTROL | +USB_EP_TYPE_ISOCHRONOUS | +USB_EP_TYPE_BULK | +USB_EP_TYPE_INTERRUPT | +USB_EP_TYPE_MASK | + +Standard USB endpoint transfer types. + +#### `enum `[`usb_langid`](#group__usb__protocol__group_1ga1f92deaf695c06566999f0c5343978c1) {#group__usb__protocol__group_1ga1f92deaf695c06566999f0c5343978c1} + + Values | Descriptions +--------------------------------|--------------------------------------------- +USB_LANGID_EN_US | English (United States) + +Standard USB language IDs for string descriptors. + +# struct `usb_setup_req_t` {#structusb__setup__req__t} + +A USB Device SETUP request. + +The data payload of SETUP packets always follows this structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bmRequestType`](#structusb__setup__req__t_1abea120ea756eb0abdb8aafb8713f61f4) | +`public uint8_t `[`bRequest`](#structusb__setup__req__t_1a1e7be110861bd4ff75c86d5214f31543) | +`public le16_t `[`wValue`](#structusb__setup__req__t_1a3f4a2e5f861f69f5ff919187c77997df) | +`public le16_t `[`wIndex`](#structusb__setup__req__t_1ab714cf061bdd655bcf61fdd06e79582f) | +`public le16_t `[`wLength`](#structusb__setup__req__t_1aa89ae35360f472f2cf0ea6374dde429e) | + +## Members + +#### `public uint8_t `[`bmRequestType`](#structusb__setup__req__t_1abea120ea756eb0abdb8aafb8713f61f4) {#structusb__setup__req__t_1abea120ea756eb0abdb8aafb8713f61f4} + +#### `public uint8_t `[`bRequest`](#structusb__setup__req__t_1a1e7be110861bd4ff75c86d5214f31543) {#structusb__setup__req__t_1a1e7be110861bd4ff75c86d5214f31543} + +#### `public le16_t `[`wValue`](#structusb__setup__req__t_1a3f4a2e5f861f69f5ff919187c77997df) {#structusb__setup__req__t_1a3f4a2e5f861f69f5ff919187c77997df} + +#### `public le16_t `[`wIndex`](#structusb__setup__req__t_1ab714cf061bdd655bcf61fdd06e79582f) {#structusb__setup__req__t_1ab714cf061bdd655bcf61fdd06e79582f} + +#### `public le16_t `[`wLength`](#structusb__setup__req__t_1aa89ae35360f472f2cf0ea6374dde429e) {#structusb__setup__req__t_1aa89ae35360f472f2cf0ea6374dde429e} + +# struct `usb_dev_desc_t` {#structusb__dev__desc__t} + +Standard USB device descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__dev__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__dev__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public le16_t `[`bcdUSB`](#structusb__dev__desc__t_1a56cc8699d8752ad2ed929093577b524d) | +`public uint8_t `[`bDeviceClass`](#structusb__dev__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4) | +`public uint8_t `[`bDeviceSubClass`](#structusb__dev__desc__t_1a260eec0b4e7279e6ecae808ca34c2604) | +`public uint8_t `[`bDeviceProtocol`](#structusb__dev__desc__t_1a44e204b5f7158f4048edcb944351ce27) | +`public uint8_t `[`bMaxPacketSize0`](#structusb__dev__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2) | +`public le16_t `[`idVendor`](#structusb__dev__desc__t_1a936f0362af0151f7370e3d18cdaa567c) | +`public le16_t `[`idProduct`](#structusb__dev__desc__t_1ae8d97f443c3dc80e3f1d37f3d45c6d57) | +`public le16_t `[`bcdDevice`](#structusb__dev__desc__t_1a55f0af10047f350be74d3e8c3884c035) | +`public uint8_t `[`iManufacturer`](#structusb__dev__desc__t_1a7ee6ae41b483f3c49d1ddb39a83a8a43) | +`public uint8_t `[`iProduct`](#structusb__dev__desc__t_1a77c33850b90ff7617243c40ce61d9168) | +`public uint8_t `[`iSerialNumber`](#structusb__dev__desc__t_1aeb129fc0d41494f69369da70d73eac11) | +`public uint8_t `[`bNumConfigurations`](#structusb__dev__desc__t_1abde4f60e84b2d9b10c27aa23bae62595) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__dev__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__dev__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__dev__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__dev__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public le16_t `[`bcdUSB`](#structusb__dev__desc__t_1a56cc8699d8752ad2ed929093577b524d) {#structusb__dev__desc__t_1a56cc8699d8752ad2ed929093577b524d} + +#### `public uint8_t `[`bDeviceClass`](#structusb__dev__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4) {#structusb__dev__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4} + +#### `public uint8_t `[`bDeviceSubClass`](#structusb__dev__desc__t_1a260eec0b4e7279e6ecae808ca34c2604) {#structusb__dev__desc__t_1a260eec0b4e7279e6ecae808ca34c2604} + +#### `public uint8_t `[`bDeviceProtocol`](#structusb__dev__desc__t_1a44e204b5f7158f4048edcb944351ce27) {#structusb__dev__desc__t_1a44e204b5f7158f4048edcb944351ce27} + +#### `public uint8_t `[`bMaxPacketSize0`](#structusb__dev__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2) {#structusb__dev__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2} + +#### `public le16_t `[`idVendor`](#structusb__dev__desc__t_1a936f0362af0151f7370e3d18cdaa567c) {#structusb__dev__desc__t_1a936f0362af0151f7370e3d18cdaa567c} + +#### `public le16_t `[`idProduct`](#structusb__dev__desc__t_1ae8d97f443c3dc80e3f1d37f3d45c6d57) {#structusb__dev__desc__t_1ae8d97f443c3dc80e3f1d37f3d45c6d57} + +#### `public le16_t `[`bcdDevice`](#structusb__dev__desc__t_1a55f0af10047f350be74d3e8c3884c035) {#structusb__dev__desc__t_1a55f0af10047f350be74d3e8c3884c035} + +#### `public uint8_t `[`iManufacturer`](#structusb__dev__desc__t_1a7ee6ae41b483f3c49d1ddb39a83a8a43) {#structusb__dev__desc__t_1a7ee6ae41b483f3c49d1ddb39a83a8a43} + +#### `public uint8_t `[`iProduct`](#structusb__dev__desc__t_1a77c33850b90ff7617243c40ce61d9168) {#structusb__dev__desc__t_1a77c33850b90ff7617243c40ce61d9168} + +#### `public uint8_t `[`iSerialNumber`](#structusb__dev__desc__t_1aeb129fc0d41494f69369da70d73eac11) {#structusb__dev__desc__t_1aeb129fc0d41494f69369da70d73eac11} + +#### `public uint8_t `[`bNumConfigurations`](#structusb__dev__desc__t_1abde4f60e84b2d9b10c27aa23bae62595) {#structusb__dev__desc__t_1abde4f60e84b2d9b10c27aa23bae62595} + +# struct `usb_dev_qual_desc_t` {#structusb__dev__qual__desc__t} + +Standard USB device qualifier descriptor structure. + +This descriptor contains information about the device when running at the "other" speed (i.e. if the device is currently operating at high speed, this descriptor can be used to determine what would change if the device was operating at full speed.) + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__dev__qual__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__dev__qual__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public le16_t `[`bcdUSB`](#structusb__dev__qual__desc__t_1a56cc8699d8752ad2ed929093577b524d) | +`public uint8_t `[`bDeviceClass`](#structusb__dev__qual__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4) | +`public uint8_t `[`bDeviceSubClass`](#structusb__dev__qual__desc__t_1a260eec0b4e7279e6ecae808ca34c2604) | +`public uint8_t `[`bDeviceProtocol`](#structusb__dev__qual__desc__t_1a44e204b5f7158f4048edcb944351ce27) | +`public uint8_t `[`bMaxPacketSize0`](#structusb__dev__qual__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2) | +`public uint8_t `[`bNumConfigurations`](#structusb__dev__qual__desc__t_1abde4f60e84b2d9b10c27aa23bae62595) | +`public uint8_t `[`bReserved`](#structusb__dev__qual__desc__t_1ab8303f57004812636de0daff446b975a) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__dev__qual__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__dev__qual__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__dev__qual__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__dev__qual__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public le16_t `[`bcdUSB`](#structusb__dev__qual__desc__t_1a56cc8699d8752ad2ed929093577b524d) {#structusb__dev__qual__desc__t_1a56cc8699d8752ad2ed929093577b524d} + +#### `public uint8_t `[`bDeviceClass`](#structusb__dev__qual__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4) {#structusb__dev__qual__desc__t_1ab8e1b1fca77a607c39bba2278623d4f4} + +#### `public uint8_t `[`bDeviceSubClass`](#structusb__dev__qual__desc__t_1a260eec0b4e7279e6ecae808ca34c2604) {#structusb__dev__qual__desc__t_1a260eec0b4e7279e6ecae808ca34c2604} + +#### `public uint8_t `[`bDeviceProtocol`](#structusb__dev__qual__desc__t_1a44e204b5f7158f4048edcb944351ce27) {#structusb__dev__qual__desc__t_1a44e204b5f7158f4048edcb944351ce27} + +#### `public uint8_t `[`bMaxPacketSize0`](#structusb__dev__qual__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2) {#structusb__dev__qual__desc__t_1a93b2c926b005917cdf2b5e7e4b3f80a2} + +#### `public uint8_t `[`bNumConfigurations`](#structusb__dev__qual__desc__t_1abde4f60e84b2d9b10c27aa23bae62595) {#structusb__dev__qual__desc__t_1abde4f60e84b2d9b10c27aa23bae62595} + +#### `public uint8_t `[`bReserved`](#structusb__dev__qual__desc__t_1ab8303f57004812636de0daff446b975a) {#structusb__dev__qual__desc__t_1ab8303f57004812636de0daff446b975a} + +# struct `usb_dev_bos_desc_t` {#structusb__dev__bos__desc__t} + +USB Device BOS descriptor structure. + +The BOS descriptor (Binary device Object Store) defines a root descriptor that is similar to the configuration descriptor, and is the base descriptor for accessing a family of related descriptors. A host can read a BOS descriptor and learn from the wTotalLength field the entire size of the device-level descriptor set, or it can read in the entire BOS descriptor set of device capabilities. The host accesses this descriptor using the GetDescriptor() request. The descriptor type in the GetDescriptor() request is set to BOS. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__dev__bos__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__dev__bos__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public le16_t `[`wTotalLength`](#structusb__dev__bos__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7) | +`public uint8_t `[`bNumDeviceCaps`](#structusb__dev__bos__desc__t_1aca1d3672075c130816f54ef305a5aa50) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__dev__bos__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__dev__bos__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__dev__bos__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__dev__bos__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public le16_t `[`wTotalLength`](#structusb__dev__bos__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7) {#structusb__dev__bos__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7} + +#### `public uint8_t `[`bNumDeviceCaps`](#structusb__dev__bos__desc__t_1aca1d3672075c130816f54ef305a5aa50) {#structusb__dev__bos__desc__t_1aca1d3672075c130816f54ef305a5aa50} + +# struct `usb_dev_capa_ext_desc_t` {#structusb__dev__capa__ext__desc__t} + +USB Device Capabilities - USB 2.0 Extension Descriptor structure. + +Defines the set of USB 1.1-specific device level capabilities. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__dev__capa__ext__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__dev__capa__ext__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public uint8_t `[`bDevCapabilityType`](#structusb__dev__capa__ext__desc__t_1a1be7f18a35c3e636c095752fbb2149c0) | +`public le32_t `[`bmAttributes`](#structusb__dev__capa__ext__desc__t_1aecf9cc6699e2f1905e31e11484095def) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__dev__capa__ext__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__dev__capa__ext__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__dev__capa__ext__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__dev__capa__ext__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public uint8_t `[`bDevCapabilityType`](#structusb__dev__capa__ext__desc__t_1a1be7f18a35c3e636c095752fbb2149c0) {#structusb__dev__capa__ext__desc__t_1a1be7f18a35c3e636c095752fbb2149c0} + +#### `public le32_t `[`bmAttributes`](#structusb__dev__capa__ext__desc__t_1aecf9cc6699e2f1905e31e11484095def) {#structusb__dev__capa__ext__desc__t_1aecf9cc6699e2f1905e31e11484095def} + +# struct `usb_dev_lpm_desc_t` {#structusb__dev__lpm__desc__t} + +USB Device LPM Descriptor structure. + +The BOS descriptor and capabilities descriptors for LPM. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_dev_bos_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__dev__bos__desc__t)` `[`bos`](#structusb__dev__lpm__desc__t_1aa1445afe8acf8bc5d942305edeb6dfd1) | +`public `[`usb_dev_capa_ext_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__dev__capa__ext__desc__t)` `[`capa_ext`](#structusb__dev__lpm__desc__t_1a260a9ee22980a1306d3dcff998fd48c7) | + +## Members + +#### `public `[`usb_dev_bos_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__dev__bos__desc__t)` `[`bos`](#structusb__dev__lpm__desc__t_1aa1445afe8acf8bc5d942305edeb6dfd1) {#structusb__dev__lpm__desc__t_1aa1445afe8acf8bc5d942305edeb6dfd1} + +#### `public `[`usb_dev_capa_ext_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__dev__capa__ext__desc__t)` `[`capa_ext`](#structusb__dev__lpm__desc__t_1a260a9ee22980a1306d3dcff998fd48c7) {#structusb__dev__lpm__desc__t_1a260a9ee22980a1306d3dcff998fd48c7} + +# struct `usb_association_desc_t` {#structusb__association__desc__t} + +Standard USB Interface Association Descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__association__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | size of this descriptor in bytes +`public uint8_t `[`bDescriptorType`](#structusb__association__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | INTERFACE descriptor type. +`public uint8_t `[`bFirstInterface`](#structusb__association__desc__t_1a85323ed61eb948bdea147d67e01ddc2d) | Number of interface. +`public uint8_t `[`bInterfaceCount`](#structusb__association__desc__t_1a9674bda677f9898106ec2b6fe5f5723d) | value to select alternate setting +`public uint8_t `[`bFunctionClass`](#structusb__association__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704) | Class code assigned by the USB. +`public uint8_t `[`bFunctionSubClass`](#structusb__association__desc__t_1ab25f749c091ce99b6868c949c4e45bc3) | Sub-class code assigned by the USB. +`public uint8_t `[`bFunctionProtocol`](#structusb__association__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c) | Protocol code assigned by the USB. +`public uint8_t `[`iFunction`](#structusb__association__desc__t_1ab84d4b3bced6c09c62350d56fd69d226) | Index of string descriptor. + +## Members + +#### `public uint8_t `[`bLength`](#structusb__association__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__association__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +size of this descriptor in bytes + +#### `public uint8_t `[`bDescriptorType`](#structusb__association__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__association__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +INTERFACE descriptor type. + +#### `public uint8_t `[`bFirstInterface`](#structusb__association__desc__t_1a85323ed61eb948bdea147d67e01ddc2d) {#structusb__association__desc__t_1a85323ed61eb948bdea147d67e01ddc2d} + +Number of interface. + +#### `public uint8_t `[`bInterfaceCount`](#structusb__association__desc__t_1a9674bda677f9898106ec2b6fe5f5723d) {#structusb__association__desc__t_1a9674bda677f9898106ec2b6fe5f5723d} + +value to select alternate setting + +#### `public uint8_t `[`bFunctionClass`](#structusb__association__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704) {#structusb__association__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704} + +Class code assigned by the USB. + +#### `public uint8_t `[`bFunctionSubClass`](#structusb__association__desc__t_1ab25f749c091ce99b6868c949c4e45bc3) {#structusb__association__desc__t_1ab25f749c091ce99b6868c949c4e45bc3} + +Sub-class code assigned by the USB. + +#### `public uint8_t `[`bFunctionProtocol`](#structusb__association__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c) {#structusb__association__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c} + +Protocol code assigned by the USB. + +#### `public uint8_t `[`iFunction`](#structusb__association__desc__t_1ab84d4b3bced6c09c62350d56fd69d226) {#structusb__association__desc__t_1ab84d4b3bced6c09c62350d56fd69d226} + +Index of string descriptor. + +# struct `usb_conf_desc_t` {#structusb__conf__desc__t} + +Standard USB configuration descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__conf__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__conf__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public le16_t `[`wTotalLength`](#structusb__conf__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7) | +`public uint8_t `[`bNumInterfaces`](#structusb__conf__desc__t_1a1ad144333e75b0d867e72f8a337cd510) | +`public uint8_t `[`bConfigurationValue`](#structusb__conf__desc__t_1aecb9ae30bca0b044d2941120f21c2b29) | +`public uint8_t `[`iConfiguration`](#structusb__conf__desc__t_1a5ad4440b4eb1935d66b154d274f8a272) | +`public uint8_t `[`bmAttributes`](#structusb__conf__desc__t_1ae7c63b4cda39953db5710012a5d91c6f) | +`public uint8_t `[`bMaxPower`](#structusb__conf__desc__t_1ad3ac74420252d7a6a03e1e9d7b481f9b) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__conf__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__conf__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__conf__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__conf__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public le16_t `[`wTotalLength`](#structusb__conf__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7) {#structusb__conf__desc__t_1aef0f5fd0160660a30f12e0c82a73f3d7} + +#### `public uint8_t `[`bNumInterfaces`](#structusb__conf__desc__t_1a1ad144333e75b0d867e72f8a337cd510) {#structusb__conf__desc__t_1a1ad144333e75b0d867e72f8a337cd510} + +#### `public uint8_t `[`bConfigurationValue`](#structusb__conf__desc__t_1aecb9ae30bca0b044d2941120f21c2b29) {#structusb__conf__desc__t_1aecb9ae30bca0b044d2941120f21c2b29} + +#### `public uint8_t `[`iConfiguration`](#structusb__conf__desc__t_1a5ad4440b4eb1935d66b154d274f8a272) {#structusb__conf__desc__t_1a5ad4440b4eb1935d66b154d274f8a272} + +#### `public uint8_t `[`bmAttributes`](#structusb__conf__desc__t_1ae7c63b4cda39953db5710012a5d91c6f) {#structusb__conf__desc__t_1ae7c63b4cda39953db5710012a5d91c6f} + +#### `public uint8_t `[`bMaxPower`](#structusb__conf__desc__t_1ad3ac74420252d7a6a03e1e9d7b481f9b) {#structusb__conf__desc__t_1ad3ac74420252d7a6a03e1e9d7b481f9b} + +# struct `usb_iad_desc_t` {#structusb__iad__desc__t} + +Standard USB association descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__iad__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | Size of this descriptor in bytes. +`public uint8_t `[`bDescriptorType`](#structusb__iad__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | Interface descriptor type. +`public uint8_t `[`bFirstInterface`](#structusb__iad__desc__t_1a85323ed61eb948bdea147d67e01ddc2d) | Number of interface. +`public uint8_t `[`bInterfaceCount`](#structusb__iad__desc__t_1a9674bda677f9898106ec2b6fe5f5723d) | value to select alternate setting +`public uint8_t `[`bFunctionClass`](#structusb__iad__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704) | Class code assigned by the USB. +`public uint8_t `[`bFunctionSubClass`](#structusb__iad__desc__t_1ab25f749c091ce99b6868c949c4e45bc3) | Sub-class code assigned by the USB. +`public uint8_t `[`bFunctionProtocol`](#structusb__iad__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c) | Protocol code assigned by the USB. +`public uint8_t `[`iFunction`](#structusb__iad__desc__t_1ab84d4b3bced6c09c62350d56fd69d226) | Index of string descriptor. + +## Members + +#### `public uint8_t `[`bLength`](#structusb__iad__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__iad__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +Size of this descriptor in bytes. + +#### `public uint8_t `[`bDescriptorType`](#structusb__iad__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__iad__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +Interface descriptor type. + +#### `public uint8_t `[`bFirstInterface`](#structusb__iad__desc__t_1a85323ed61eb948bdea147d67e01ddc2d) {#structusb__iad__desc__t_1a85323ed61eb948bdea147d67e01ddc2d} + +Number of interface. + +#### `public uint8_t `[`bInterfaceCount`](#structusb__iad__desc__t_1a9674bda677f9898106ec2b6fe5f5723d) {#structusb__iad__desc__t_1a9674bda677f9898106ec2b6fe5f5723d} + +value to select alternate setting + +#### `public uint8_t `[`bFunctionClass`](#structusb__iad__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704) {#structusb__iad__desc__t_1a1ed25bc3320ca90e4d3acb4410aea704} + +Class code assigned by the USB. + +#### `public uint8_t `[`bFunctionSubClass`](#structusb__iad__desc__t_1ab25f749c091ce99b6868c949c4e45bc3) {#structusb__iad__desc__t_1ab25f749c091ce99b6868c949c4e45bc3} + +Sub-class code assigned by the USB. + +#### `public uint8_t `[`bFunctionProtocol`](#structusb__iad__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c) {#structusb__iad__desc__t_1a2b3b905ab34e6e28b57c3ddc51b3487c} + +Protocol code assigned by the USB. + +#### `public uint8_t `[`iFunction`](#structusb__iad__desc__t_1ab84d4b3bced6c09c62350d56fd69d226) {#structusb__iad__desc__t_1ab84d4b3bced6c09c62350d56fd69d226} + +Index of string descriptor. + +# struct `usb_iface_desc_t` {#structusb__iface__desc__t} + +Standard USB interface descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__iface__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__iface__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public uint8_t `[`bInterfaceNumber`](#structusb__iface__desc__t_1a3d66d88c5e928462aef62633449f1eb0) | +`public uint8_t `[`bAlternateSetting`](#structusb__iface__desc__t_1a4cdd7aab185365e51a1e722f43073b8c) | +`public uint8_t `[`bNumEndpoints`](#structusb__iface__desc__t_1acec2e7d68271baace354a0539f3d7e3d) | +`public uint8_t `[`bInterfaceClass`](#structusb__iface__desc__t_1ae899427763e325f03241afc69a6e1ea0) | +`public uint8_t `[`bInterfaceSubClass`](#structusb__iface__desc__t_1a3b3919d1203cd42550d77287f7585595) | +`public uint8_t `[`bInterfaceProtocol`](#structusb__iface__desc__t_1a6872c4ec51fd061e2955f84d97bea2a7) | +`public uint8_t `[`iInterface`](#structusb__iface__desc__t_1a2e4535908d90f195c6347a91e15b544d) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__iface__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__iface__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__iface__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__iface__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public uint8_t `[`bInterfaceNumber`](#structusb__iface__desc__t_1a3d66d88c5e928462aef62633449f1eb0) {#structusb__iface__desc__t_1a3d66d88c5e928462aef62633449f1eb0} + +#### `public uint8_t `[`bAlternateSetting`](#structusb__iface__desc__t_1a4cdd7aab185365e51a1e722f43073b8c) {#structusb__iface__desc__t_1a4cdd7aab185365e51a1e722f43073b8c} + +#### `public uint8_t `[`bNumEndpoints`](#structusb__iface__desc__t_1acec2e7d68271baace354a0539f3d7e3d) {#structusb__iface__desc__t_1acec2e7d68271baace354a0539f3d7e3d} + +#### `public uint8_t `[`bInterfaceClass`](#structusb__iface__desc__t_1ae899427763e325f03241afc69a6e1ea0) {#structusb__iface__desc__t_1ae899427763e325f03241afc69a6e1ea0} + +#### `public uint8_t `[`bInterfaceSubClass`](#structusb__iface__desc__t_1a3b3919d1203cd42550d77287f7585595) {#structusb__iface__desc__t_1a3b3919d1203cd42550d77287f7585595} + +#### `public uint8_t `[`bInterfaceProtocol`](#structusb__iface__desc__t_1a6872c4ec51fd061e2955f84d97bea2a7) {#structusb__iface__desc__t_1a6872c4ec51fd061e2955f84d97bea2a7} + +#### `public uint8_t `[`iInterface`](#structusb__iface__desc__t_1a2e4535908d90f195c6347a91e15b544d) {#structusb__iface__desc__t_1a2e4535908d90f195c6347a91e15b544d} + +# struct `usb_ep_desc_t` {#structusb__ep__desc__t} + +Standard USB endpoint descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__ep__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__ep__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | +`public uint8_t `[`bEndpointAddress`](#structusb__ep__desc__t_1a527afb0f25cdd442d8d32c7df8e18c45) | +`public uint8_t `[`bmAttributes`](#structusb__ep__desc__t_1ae7c63b4cda39953db5710012a5d91c6f) | +`public le16_t `[`wMaxPacketSize`](#structusb__ep__desc__t_1ad083d80a481cb62796a7183f9240c914) | +`public uint8_t `[`bInterval`](#structusb__ep__desc__t_1aff92277eea8536f7de1a88d818c91b9e) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__ep__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__ep__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__ep__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__ep__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +#### `public uint8_t `[`bEndpointAddress`](#structusb__ep__desc__t_1a527afb0f25cdd442d8d32c7df8e18c45) {#structusb__ep__desc__t_1a527afb0f25cdd442d8d32c7df8e18c45} + +#### `public uint8_t `[`bmAttributes`](#structusb__ep__desc__t_1ae7c63b4cda39953db5710012a5d91c6f) {#structusb__ep__desc__t_1ae7c63b4cda39953db5710012a5d91c6f} + +#### `public le16_t `[`wMaxPacketSize`](#structusb__ep__desc__t_1ad083d80a481cb62796a7183f9240c914) {#structusb__ep__desc__t_1ad083d80a481cb62796a7183f9240c914} + +#### `public uint8_t `[`bInterval`](#structusb__ep__desc__t_1aff92277eea8536f7de1a88d818c91b9e) {#structusb__ep__desc__t_1aff92277eea8536f7de1a88d818c91b9e} + +# struct `usb_str_desc_t` {#structusb__str__desc__t} + +A standard USB string descriptor structure. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public uint8_t `[`bLength`](#structusb__str__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) | +`public uint8_t `[`bDescriptorType`](#structusb__str__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) | + +## Members + +#### `public uint8_t `[`bLength`](#structusb__str__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8) {#structusb__str__desc__t_1a1deca1f1d6e5815b290e6e1015bce5b8} + +#### `public uint8_t `[`bDescriptorType`](#structusb__str__desc__t_1a67d7027b9eb9ed268d28e84fbc675707) {#structusb__str__desc__t_1a67d7027b9eb9ed268d28e84fbc675707} + +# struct `usb_str_lgid_desc_t` {#structusb__str__lgid__desc__t} + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`public `[`usb_str_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__str__desc__t)` `[`desc`](#structusb__str__lgid__desc__t_1a6b9de937ba1cb40f4b82094a8644c528) | +`public le16_t `[`string`](#structusb__str__lgid__desc__t_1a79364ecffd40a6c3218c408b4891c460) | + +## Members + +#### `public `[`usb_str_desc_t`](.build/docs/internals_usb_protocol_group.md#structusb__str__desc__t)` `[`desc`](#structusb__str__lgid__desc__t_1a6b9de937ba1cb40f4b82094a8644c528) {#structusb__str__lgid__desc__t_1a6b9de937ba1cb40f4b82094a8644c528} + +#### `public le16_t `[`string`](#structusb__str__lgid__desc__t_1a79364ecffd40a6c3218c408b4891c460) {#structusb__str__lgid__desc__t_1a79364ecffd40a6c3218c408b4891c460} + diff --git a/isp_flashing_guide.md b/isp_flashing_guide.md new file mode 100644 index 00000000000..9a65fe1154d --- /dev/null +++ b/isp_flashing_guide.md @@ -0,0 +1,253 @@ +# ISP Flashing Guide + +ISP flashing (also known as ICSP flashing) is the process of programming a microcontroller directly. This allows you to replace the bootloader, or change the "fuses" on the controller, which control a number of hardware- and software-related functions, such as the speed of the controller, how it boots, and other options. + +The main use of ISP flashing for QMK is flashing or replacing the bootloader on your AVR-based controller (Pro Micros, or V-USB chips). + +?> This is only for programming AVR based boards, such as the Pro Micro or other ATmega controllers. It is not for Arm controllers, such as the Proton C. + +## Dealing with Corrupted Bootloaders + +If you're having trouble flashing/erasing your board, and running into cryptic error messages like any of the following for a DFU based controller: + + libusb: warning [darwin_transfer_status] transfer error: timed out + dfu.c:844: -ETIMEDOUT: Transfer timed out, NAK 0xffffffc4 (-60) + atmel.c:1627: atmel_flash: flash data dfu_download failed. + atmel.c:1629: Expected message length of 1072, got -60. + atmel.c:1434: Error flashing the block: err -2. + ERROR + Memory write error, use debug for more info. + commands.c:360: Error writing memory data. (err -4) + + dfu.c:844: -EPIPE: a) Babble detect or b) Endpoint stalled 0xffffffe0 (-32) + Device is write protected. + dfu.c:252: dfu_clear_status( 0x7fff4fc2ea80 ) + atmel.c:1434: Error flashing the block: err -2. + ERROR + Memory write error, use debug for more info. + commands.c:360: Error writing memory data. (err -4) + +Or, if you see this sort of message for a Pro Micro based controller: + + avrdude: butterfly_recv(): programmer is not responding + avrdude: butterfly_recv(): programmer is not responding + avrdude: verification error, first mismatch at byte 0x002a + 0x2b != 0x75 + avrdude: verification error; content mismatch + avrdude: verification error; content mismatch + + +You're likely going to need to ISP flash your board/device to get it working again. + +## Hardware Needed + +You'll need one of the following to actually perform the ISP flashing (followed by the protocol they use): + +* [SparkFun PocketAVR](https://www.sparkfun.com/products/9825) - (USB Tiny) +* [USBtinyISP AVR Programmer Kit](https://www.adafruit.com/product/46) - (USB Tiny) +* [Teensy 2.0](https://www.pjrc.com/store/teensy.html) - (avrisp) +* [Pro Micro](https://www.sparkfun.com/products/12640) - (avrisp) +* [Bus Pirate](https://www.adafruit.com/product/237) - (buspirate) + +There are other devices that can be used to ISP flash, but these are the main ones. Also, all product links are to the official versions. You can source them elsewhere. + +You'll also need something to wire your "ISP Programmer" to the device that you're programming. Some PCBs may have ISP headers that you can use directly, but this often isn't the case, so you'll likely need to solder to the controller itself or to different switches or other components. + +### The ISP Firmware + +The Teensy and Pro Micro controllers will need you to flash the ISP firmware to the controllers before you can use them as an ISP programmer. The rest of the hardware should come preprogrammed. So, for these controllers, download the correct hex file, and flash it first. + +* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`) +* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) (`10/B6`) + +Once you've flashed your controller, you won't need this hex file anymore. + +## Software Needed + +The QMK Toolbox can be used for most (all) of this. + +However, you can grab the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to flash your Teensy 2.0 board, if you are using that. Or you can use `avrdude` (installed as part of `qmk_install.sh`), or [AVRDUDESS](https://blog.zakkemble.net/avrdudess-a-gui-for-avrdude/) (for Windows) to flash the Pro Micro, and the ISP flashing. + + +## Wiring + +This is pretty straight-forward - we'll be connecting like-things to like-things in the following manner. + +### SparkFun Pocket AVR + + PocketAVR RST <-> Keyboard RESET + PocketAVR SCLK <-> Keyboard B1 (SCLK) + PocketAVR MOSI <-> Keyboard B2 (MOSI) + PocketAVR MISO <-> Keyboard B3 (MISO) + PocketAVR VCC <-> Keyboard VCC + PocketAVR GND <-> Keyboard GND + +### Teensy 2.0 + + Teensy B0 <-> Keyboard RESET + Teensy B1 <-> Keyboard B1 (SCLK) + Teensy B2 <-> Keyboard B2 (MOSI) + Teensy B3 <-> Keyboard B3 (MISO) + Teensy VCC <-> Keyboard VCC + Teensy GND <-> Keyboard GND + +!> Note that the B0 pin on the Teensy is wired to the RESET/RST pin on the keyboard's controller. ***DO NOT*** wire the RESET pin on the Teensy to the RESET on the keyboard. + +### Pro Micro + + Pro Micro 10 (B6) <-> Keyboard RESET + Pro Micro 15 (B1) <-> Keyboard B1 (SCLK) + Pro Micro 16 (B2) <-> Keyboard B2 (MOSI) + Pro Micro 14 (B3) <-> Keyboard B3 (MISO) + Pro Micro VCC <-> Keyboard VCC + Pro Micro GND <-> Keyboard GND + +!> Note that the 10/B6 pin on the Pro Micro is wired to the RESET/RST pin on the keyboard's controller. ***DO NOT*** wire the RESET pin on the Pro Micro to the RESET on the keyboard. + + +## Flashing Your Keyboard + +After you have your ISP programmer set up, and wired to your keyboard, it's time to flash your keyboard. + +### The Bootloader File + +The simplest and quickest way to get things back to normal is to flash only a bootloader to the keyboard. Once this is done, you can connect the keyboard normally and flash the keyboard like you normally would. + +You can find the stock bootloaders in the [`util/` folder](https://github.com/qmk/qmk_firmware/tree/master/util). Be sure to flash the correct bootloader for your chip: + +* **Atmel DFU** + * [ATmega16U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega16u4_1.0.1.hex) + * [ATmega32U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1.0.0.hex) + * [AT90USB64](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb64_1.0.0.hex) + * [AT90USB128](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128_1.0.1.hex) +* **Caterina** + * [Pro Micro (5V/16MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro16.hex) + * [Pro Micro (3.3V/8MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro8.hex) +* **BootloadHID (PS2AVRGB)** + * [ATmega32A](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_ps2avrgb_bootloadhid_1.0.1.hex) + +If you're not sure what your board uses, look in the `rules.mk` file for the keyboard in QMK. The `MCU` and `BOOTLOADER` lines will have the value you need. It may differ between different versions of the board. + +### Production Techniques + +If you'd like to flash both the bootloader **and** the regular firmware at the same time, there are two options to do so. Manually, or with the `:production` target when compiling. + +To do this manually: + +1. Open the original firmware .hex file in a text editor +2. Remove the last line (which should be `:00000001FF` - this is an EOF message) +3. Copy the entire bootloader's contents onto a new line (with no empty lines between) and paste it at the end of the original file +4. Save it as a new file by naming it `__production.hex` + +?> It's possible to use other bootloaders here in the same way, but __you need a bootloader__, otherwise you'll have to use ISP again to write new firmware to your keyboard. + +#### Create QMK DFU Bootloader and Production images + +You can create the firmware, the QMK DFU Bootloader and the production firmware images for the board using the `:production` target when compiling. Once this is done, you'll see three files: +* `_.hex` +* `__bootloader.hex` +* `__production.hex` + +The QMK DFU bootloader has only really been tested on `atmega32u4` controllers (such as the AVR based Planck boards, and the Pro Micro), and hasn't been tested on other controllers. However, it will definitely not work on V-USB controllers, such as the `atmega32a` or `atmega328p`. + +You can flash either the bootloader or the production firmware file. The production firmware file will take a lot longer to flash, since it's flashing a lot more data. + +?> Note: You should stay with the same bootloader. If you're using DFU already, switching to QMK DFU is fine. But flashing QMK DFU onto a Pro Micro, for instance, has additional steps needed. + +## Flashing Your Bootloader/Production File + +Make sure your keyboard is unplugged from any device, and plug in your ISP Programmer. + +If you want to change bootloader types, You'll need to use the command line. + +### QMK Toolbox + +1. `AVRISP device connected` or `USB Tiny device connected` will show up in yellow +2. Select the correct bootloader/production .hex file with the `Open` dialog (spaces can't be in the path) +3. Be sure the correct `Microcontroller` option for the keyboard you're flashing (not the ISP programmer) is selected +4. Hit `Flash` +5. Wait, as nothing will output for a while, especially with production files + +If the verification and fuse checks are ok, you're done! Your board may restart automatically, otherwise, unplug your Teensy and plug in your keyboard - you can leave your Teensy wired to your keyboard while testing things, but it's recommended that you desolder it/remove the wiring once you're sure everything works. + +### Command Line + +Open a terminal (`cmd` on Windows, for instance) and navigate to your where your modified .hex file is. We'll pretend this file is called `main.hex`, and that your Teensy 2.0 is on the `COM3` port - if you're unsure, you can open your Device Manager, and look for `Ports > USB Serial Device`. Use that COM port here. You can confirm it's the right port with: + + avrdude -c avrisp -P COM3 -p atmega32u4 + +and you should get something like the following output: + + avrdude: AVR device initialized and ready to accept instructions + + Reading | ################################################## | 100% 0.02s + + avrdude: Device signature = 0x1e9587 + + avrdude: safemode: Fuses OK + + avrdude done. Thank you. + +Since our keyboard uses an `atmega32u4` (common), that is the chip we'll specify. This is the full command: + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i + +If your board uses an `atmega32a` (e.g. on a jj40), the command is this (the extra code at the end sets the fuses correctly): + + avrdude -c avrisp -P COM3 -p atmega32 -U flash:w:main.hex:i -U hfuse:w:0xD0:m -U lfuse:w:0x0F:m + +You should see a couple of progress bars, then you should see: + + avrdude: verifying ... + avrdude: 32768 bytes of flash verified + + avrdude: safemode: Fuses OK + + avrdude done. Thank you. + +Which means everything should be ok! Your board may restart automatically, otherwise, unplug your Teensy and plug in your keyboard - you can leave your Teensy wired to your keyboard while testing things, but it's recommended that you desolder it/remove the wiring once you're sure everything works. + +If you're using a SparkFun PocketAVR Programmer, or another USB Tiny based ISP programmer, you will want to use something like this: + + avrdude -c usbtiny -P usb -p atmega32u4 + +#### Advanced: Changing Fuses + +If you're switching bootloaders, such as flashing QMK DFU on a Pro Micro, you will need to change the fuses, in additional to flashing the bootloader hex file. This is because `caterina` (the Pro Micro bootloader) and `dfu` handle the startup routines differently, and that behavior is controlled by the fuses. + +!> This is one area that it is very important to be careful, as changing fuses is one of the ways that you can permanently brick your controller. + +For this, we are assuming the 5V 16MHz versions of the `atmega32u4` (such as the 5V Pro Micro). + +For DFU on the `atmega32u4`, these are the fuse settings that you want: + +| Fuse | Setting | +|----------|------------------| +| Low | `0x5E` | +| High | `0xD9` or `0x99` | +| Extended | `0xC3` | + +The High fuse can be 0xD9 or 0x99. The difference is that 0xD9 disables JTAG, which QMK Firmware disables via software as well, while 0x99 doesn't disable JTAG. + +To set this add `-U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m` to your command. So the final command should look something like: + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m + +For Caterina on the `atmega32u4`, these are the fuse settings that you want: + +| Fuse | Setting| +|----------|--------| +| Low | `0xFF` | +| High | `0xD8` | +| Extended | `0xCB` | + +To set this add `-U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m` to your command. So the final command should look something like: + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m + + +If you are using a different controller or want different configuration, you can use [this AVR Fuse Calculator](http://www.engbedded.com/fusecalc/) to find a better value for you. + +## Help + +If you have any questions/problems, feel free to [open an issue](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/ja/README.md b/ja/README.md new file mode 100644 index 00000000000..c02a14b487c --- /dev/null +++ b/ja/README.md @@ -0,0 +1,48 @@ +# Quantum Mechanical Keyboard Firmware + + + +[![現在のバージョン](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![ビルド状態](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![ドキュメントの状態](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub 貢献者](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub フォーク](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## QMK ファームウェアとは何でしょうか? + +QMK (*Quantum Mechanical Keyboard*)は、コンピュータ入力デバイスの開発を中心としたオープンソースコミュニティです。コミュニティには、キーボード、マウス、MIDI デバイスなど、全ての種類の入力デバイスが含まれます。協力者の中心グループは、[QMK ファームウェア](https://github.com/qmk/qmk_firmware)、[QMK Configurator](https://config.qmk.fm)、[QMK ツールボックス](https://github.com/qmk/qmk_toolbox)、[qmk.fm](https://qmk.fm)、そして、このドキュメントを、あなたのようなコミュニティメンバーの助けを借りて保守しています。 + +## 始めましょう + +QMK は初めてですか?始めるには2つの方法があります: + +* 基本: [QMK Configurator](https://config.qmk.fm) + * ドロップダウンからあなたのキーボードを選択し、キーボードをプログラムします。 + * 見ることができる [紹介ビデオ](https://www.youtube.com/watch?v=-imgglzDMdY) があります。 + * 読むことができる概要 [ドキュメント](ja/newbs_building_firmware_configurator.md) があります。 +* 発展: [ソースを使用します](ja/newbs.md) + * より強力ですが、使うのはより困難です。 + +## 自分用にアレンジします + +QMK には、探求すべき多くの[機能](ja/features.md)と、深く知るためのリファレンスドキュメントがたくさんあります。ほとんどの機能は[キーマップ](ja/keymap.md)を変更し、[キーコード](ja/keycodes.md)を変更することで活用されます。 + +## 手助けが必要ですか? + +[サポートページ](ja/support.md) をチェックして、QMK の使い方について手助けを得る方法を確認してください。 + +## 貢献する + +QMK コミュニティに貢献する方法はたくさんあります。始める最も簡単な方法は、それを使って友人に QMK という単語を広めることです。 + +* フォーラムやチャットルームで人々を支援します: + * [/r/olkb](https://www.reddit.com/r/olkb/) + * [Discord サーバ](https://discord.gg/Uq7gcHh) +* 下にある「Edit This Page」をクリックしてドキュメントに貢献します +* [ドキュメントをあなたの言語に翻訳します](ja/translating.md) +* [バグを報告します](https://github.com/qmk/qmk_firmware/issues/new/choose) +* [プルリクエストを開きます](ja/contributing.md) diff --git a/ja/_summary.md b/ja/_summary.md new file mode 100644 index 00000000000..cf2e37aaf4d --- /dev/null +++ b/ja/_summary.md @@ -0,0 +1,177 @@ +* チュートリアル + * [入門](ja/newbs.md) + * [セットアップ](ja/newbs_getting_started.md) + * [初めてのファームウェアの構築](ja/newbs_building_firmware.md) + * [ファームウェアのフラッシュ](ja/newbs_flashing.md) + * [テストとデバッグ](ja/newbs_testing_debugging.md) + * [手助けを得る/サポート](ja/support.md) + * [他のリソース](ja/newbs_learn_more_resources.md) + * [シラバス](ja/syllabus.md) + +* FAQ + * [一般的な FAQ](ja/faq_general.md) + * [QMK のビルド/コンパイル](ja/faq_build.md) + * [QMK のデバッグ/トラブルシューティング](ja/faq_debug.md) + * [キーマップ FAQ](ja/faq_keymap.md) + * [用語](ja/reference_glossary.md) + +* Configurator + * [概要](ja/newbs_building_firmware_configurator.md) + * [ステップ・バイ・ステップ](ja/configurator_step_by_step.md) + * [トラブルシューティング](ja/configurator_troubleshooting.md) + * QMK API + * [概要](ja/api_overview.md) + * [API ドキュメント](ja/api_docs.md) + * [キーボードサポート](ja/reference_configurator_support.md) + +* CLI + * [概要](ja/cli.md) + * [設定](ja/cli_configuration.md) + * [コマンド](ja/cli_commands.md) + +* QMK を使う + * ガイド + * [機能のカスタマイズ](ja/custom_quantum_functions.md) + * [Zadig を使ったドライバのインストール](ja/driver_installation_zadig.md) + * [キーマップの概要](ja/keymap.md) + * 開発環境 + * [Docker のガイド](ja/getting_started_docker.md) + * [Vagrant のガイド](ja/getting_started_vagrant.md) + * 書き込み + * [書き込み](ja/flashing.md) + * [ATmega32A の書き込み (ps2avrgb)](ja/flashing_bootloadhid.md) + * IDE + * [Eclipse で QMK を使用](ja/other_eclipse.md) + * [VSCode で QMK を使用](ja/other_vscode.md) + * Git のベストプラクティス + * [入門](ja/newbs_git_best_practices.md) + * [フォーク](ja/newbs_git_using_your_master_branch.md) + * [マージの競合の解決](ja/newbs_git_resolving_merge_conflicts.md) + * [ブランチの修正](ja/newbs_git_resynchronize_a_branch.md) + * キーボードを作る + * [Hand Wiring ガイド](ja/hand_wire.md) + * [ISP 書き込みガイド](ja/isp_flashing_guide.md) + + * 単純なキーコード + * [完全なリスト](ja/keycodes.md) + * [基本的なキーコード](ja/keycodes_basic.md) + * [言語固有のキーコード](ja/reference_keymap_extras.md) + * [修飾キー](ja/feature_advanced_keycodes.md) + * [Quantum キーコード](ja/quantum_keycodes.md) + + * 高度なキーコード + * [コマンド](ja/feature_command.md) + * [動的マクロ](ja/feature_dynamic_macros.md) + * [グレイブ エスケープ](ja/feature_grave_esc.md) + * [リーダーキー](ja/feature_leader_key.md) + * [モッドタップ](ja/mod_tap.md) + * [マクロ](ja/feature_macros.md) + * [マウスキー](ja/feature_mouse_keys.md) + * [Space Cadet Shift](ja/feature_space_cadet.md) + * [US ANSI シフトキー](ja/keycodes_us_ansi_shifted.md) + + * ソフトウェア機能 + * [自動シフト](ja/feature_auto_shift.md) + * [コンボ](ja/feature_combo.md) + * [デバウンス API](ja/feature_debounce_type.md) + * [キーロック](ja/feature_key_lock.md) + * [レイヤー](ja/feature_layers.md) + * [ワンショットキー](ja/one_shot_keys.md) + * [ポインティング デバイス](ja/feature_pointing_device.md) + * [ロー HID](ja/feature_rawhid.md) + * [スワップハンド](ja/feature_swap_hands.md) + * [タップダンス](ja/feature_tap_dance.md) + * [タップホールド設定](ja/tap_hold.md) + * [ターミナル](ja/feature_terminal.md) + * [ユニコード](ja/feature_unicode.md) + * [ユーザスペース](ja/feature_userspace.md) + * [WPM 計算](ja/feature_wpm.md) + + * ハードウェア機能 + * 表示 + * [HD44780 LCD コントローラ](ja/feature_hd44780.md) + * [OLED ドライバ](ja/feature_oled_driver.md) + * 電飾 + * [バックライト](ja/feature_backlight.md) + * [LED マトリックス](ja/feature_led_matrix.md) + * [RGB ライト](ja/feature_rgblight.md) + * [RGB マトリックス](ja/feature_rgb_matrix.md) + * [オーディオ](ja/feature_audio.md) + * [Bluetooth](ja/feature_bluetooth.md) + * [ブートマジック](ja/feature_bootmagic.md) + * [カスタムマトリックス](ja/custom_matrix.md) + * [DIP スイッチ](ja/feature_dip_switch.md) + * [エンコーダ](ja/feature_encoders.md) + * [触覚フィードバック](ja/feature_haptic_feedback.md) + * [Proton C 変換](ja/proton_c_conversion.md) + * [PS/2 マウス](ja/feature_ps2_mouse.md) + * [分割キーボード](ja/feature_split_keyboard.md) + * [速記](ja/feature_stenography.md) + * [感熱式プリンタ](ja/feature_thermal_printer.md) + * [Velocikey](ja/feature_velocikey.md) + +* QMK の開発 + * [PR チェックリスト](ja/pr_checklist.md) + * 互換性を破る変更/Breaking changes + * [概要](ja/breaking_changes.md) + * [プルリクエストにフラグが付けられた](ja/breaking_changes_instructions.md) + * 履歴 + * [2020年8月29日](ja/ChangeLog/20200829.md) + * [2020年5月30日](ja/ChangeLog/20200530.md) + * [2020年2月29日](ja/ChangeLog/20200229.md) + * [2019年8月30日](ja/ChangeLog/20190830.md) + + * C 開発 + * [ARM デバッグ ガイド](ja/arm_debugging.md) + * [AVR プロセッサ](ja/hardware_avr.md) + * [コーディング規約](ja/coding_conventions_c.md) + * [互換性のあるマイクロコントローラ](ja/compatible_microcontrollers.md) + * [ドライバ](ja/hardware_drivers.md) + * [ADC ドライバ](ja/adc_driver.md) + * [I2C ドライバ](ja/i2c_driver.md) + * [SPI ドライバ](ja/spi_driver.md) + * [WS2812 ドライバ](ja/ws2812_driver.md) + * [EEPROM ドライバ](ja/eeprom_driver.md) + * [シリアル ドライバ](ja/serial_driver.md) + * [GPIO 制御](ja/internals_gpio_control.md) + * [キーボード ガイドライン](ja/hardware_keyboard_guidelines.md) + + * Python 開発 + * [コーディング規約](ja/coding_conventions_python.md) + * [QMK CLI 開発](ja/cli_development.md) + + * Configurator 開発 + * QMK API + * [開発環境](ja/api_development_environment.md) + * [アーキテクチャの概要](ja/api_development_overview.md) + + * ハードウェアプラットフォーム開発 + * Arm/ChibiOS + * [MCU の選択](ja/platformdev_selecting_arm_mcu.md) + * [早期初期化](ja/platformdev_chibios_earlyinit.md) + + * QMK Reference + * [QMK への貢献](ja/contributing.md) + * [QMK ドキュメントの翻訳](ja/translating.md) + * [設定オプション](ja/config_options.md) + * [Make ドキュメント](ja/getting_started_make_guide.md) + * [ドキュメント ベストプラクティス](ja/documentation_best_practices.md) + * [ドキュメント テンプレート](ja/documentation_templates.md) + * [コミュニティレイアウト](ja/feature_layouts.md) + * [ユニットテスト](ja/unit_testing.md) + * [便利な関数](ja/ref_functions.md) + * [info.json 形式](ja/reference_info_json.md) + + * より深く知るために + * [キーボードがどのように動作するか](ja/how_keyboards_work.md) + * [マトリックスがどのように動作するか](ja/how_a_matrix_works.md) + * [QMK を理解する](ja/understanding_qmk.md) + + * QMK の内部詳細(作成中) + * [定義](ja/internals_defines.md) + * [入力コールバック登録](ja/internals_input_callback_reg.md) + * [Midi デバイス](ja/internals_midi_device.md) + * [Midi デバイスのセットアップ手順](ja/internals_midi_device_setup_process.md) + * [Midi ユーティリティ](ja/internals_midi_util.md) + * [Midi 送信関数](ja/internals_send_functions.md) + * [Sysex Tools](ja/internals_sysex_tools.md) diff --git a/ja/api_development_environment.md b/ja/api_development_environment.md new file mode 100644 index 00000000000..8dce1ba2fd6 --- /dev/null +++ b/ja/api_development_environment.md @@ -0,0 +1,8 @@ +# 開発環境のセットアップ + + + +開発環境をセットアップするには、[qmk_web_stack](https://github.com/qmk/qmk_web_stack) に行ってください。 diff --git a/ja/api_development_overview.md b/ja/api_development_overview.md new file mode 100644 index 00000000000..0612507b4d8 --- /dev/null +++ b/ja/api_development_overview.md @@ -0,0 +1,49 @@ +# QMK コンパイラ開発ガイド + + + +このページでは、開発者に QMK コンパイラを紹介しようと思います。コードを読まなければならないような核心となる詳細に立ち入って調べることはしません。ここで得られるものは、コードを読んで理解を深めるためのフレームワークです。 + +# 概要 + +QMK Compile API は、いくつかの可動部分からできています: + +![構造図](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg) + +API クライアントは API サービスと排他的にやりとりをします。ここでジョブをサブミットし、状態を調べ、結果をダウンロードします。API サービスはコンパイルジョブを [Redis Queue](https://python-rq.org) に挿入し、それらのジョブの結果について RQ と S3 の両方を調べます。 + +ワーカーは RQ から新しいコンパイルジョブを取り出し、ソースとバイナリを S3 互換のストレージエンジンにアップロードします。 + +# ワーカー + +QMK コンパイラワーカーは実際のビルド作業に責任を持ちます。ワーカーは RQ からジョブを取り出し、ジョブを完了するためにいくつかの事を行います: + +* 新しい qmk_firmware のチェックアウトを作成する +* 指定されたレイヤーとキーボードメタデータを使って `keymap.c` をビルドする +* ファームウェアをビルドする +* ソースのコピーを zip 形式で圧縮する +* ファームウェア、ソースの zip ファイル、メタデータファイルを S3 にアップロードする +* ジョブの状態を RQ に送信する + +# API サービス + +API サービスは比較的単純な Flask アプリケーションです。理解しておくべきことが幾つかあります。 + +## @app.route('/v1/compile', methods=['POST']) + +これは API の主なエントリーポイントです。クライアントとのやりとりはここから開始されます。クライアントはキーボードを表す JSON ドキュメントを POST し、API はコンパイルジョブをサブミットする前にいくらかの(とても)基本的な検証を行います。 + +## @app.route('/v1/compile/<string:job_id>', methods=['GET']) + +これは最もよく呼ばれるエンドポイントです。ジョブの詳細が redis から利用可能であればそれを取り出し、そうでなければ S3 からキャッシュされたジョブの詳細を取り出します。 + +## @app.route('/v1/compile/<string:job_id>/download', methods=['GET']) + +このメソッドによりユーザはコンパイルされたファームウェアファイルをダウンロードすることができます。 + +## @app.route('/v1/compile/<string:job_id>/source', methods=['GET']) + +このメソッドによりユーザはファームウェアのソースをダウンロードすることができます。 diff --git a/ja/api_docs.md b/ja/api_docs.md new file mode 100644 index 00000000000..b483c045e64 --- /dev/null +++ b/ja/api_docs.md @@ -0,0 +1,73 @@ +# QMK API + + + +このページは QMK API の使い方を説明します。もしあなたがアプリケーション開発者であれば、全ての [QMK](https://qmk.fm) キーボードのファームウェアをコンパイルするために、この API を使うことができます。 + +## 概要 + +このサービスは、カスタムキーマップをコンパイルするための非同期 API です。API に 何らかの JSON を POST し、定期的に状態をチェックし、ファームウェアのコンパイルが完了していれば、結果のファームウェアと(もし希望すれば)そのファームウェアのソースコードをダウンロードすることができます。 + +#### JSON ペイロードの例: + +```json +{ + "keyboard": "clueboard/66/rev2", + "keymap": "my_awesome_keymap", + "layout": "LAYOUT_all", + "layers": [ + ["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"], + ["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"], + ["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"] + ] +} +``` + +ご覧のとおり、ペイロードにはファームウェアを作成および生成するために必要なキーボードの全ての側面を記述します。各レイヤーは QMK キーコードの1つのリストで、キーボードの `LAYOUT` マクロと同じ長さです。もしキーボードが複数の `LAYOUT` マクロをサポートする場合、どのマクロを使うかを指定することができます。 + +## コンパイルジョブのサブミット + +キーマップをファームウェアにコンパイルするには、単純に JSON を `/v1/compile` エンドポイントに POST します。以下の例では、JSON ペイロードを `json_data` という名前のファイルに配置しています。 + +``` +$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" http://api.qmk.fm/v1/compile +{ + "enqueued": true, + "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6" +} +``` + +## 状態のチェック + +キーマップをサブミットした後で、簡単な HTTP GET 呼び出しを使って状態をチェックすることができます: + +``` +$ curl http://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6 +{ + "created_at": "Sat, 19 Aug 2017 21:39:12 GMT", + "enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT", + "id": "f5f9b992-73b4-479b-8236-df1deb37c163", + "status": "running", + "result": null +} +``` + +これは、ジョブをキューに入れることに成功し、現在実行中であることを示しています。5つの状態がありえます: + +* **failed**: なんらかの理由でコンパイルサービスが失敗しました。 +* **finished**: コンパイルが完了し、結果を見るには `result` をチェックする必要があります。 +* **queued**: キーマップはコンパイルサーバが利用可能になるのを待っています。 +* **running**: コンパイルが進行中で、まもなく完了するはずです。 +* **unknown**: 深刻なエラーが発生し、[バグを報告](https://github.com/qmk/qmk_compiler/issues)する必要があります。 + +## 完了した結果を検証 + +コンパイルジョブが完了したら、`result` キーをチェックします。このキーの値は幾つかの情報を含むハッシュです: + +* `firmware_binary_url`: 書き込み可能なファームウェアの URL のリスト +* `firmware_keymap_url`: `keymap.c` の URL のリスト +* `firmware_source_url`: ファームウェアの完全なソースコードの URL のリスト +* `output`: このコンパイルジョブの stdout と stderr。エラーはここで見つけることができます。 diff --git a/ja/api_overview.md b/ja/api_overview.md new file mode 100644 index 00000000000..18b8eae10f3 --- /dev/null +++ b/ja/api_overview.md @@ -0,0 +1,20 @@ +# QMK API + + + +QMK API は、Web と GUI ツールが [QMK](http://qmk.fm/) によってサポートされるキーボード用の任意のキーマップをコンパイルするために使うことができる、非同期 API を提供します。標準のキーマップテンプレートは、C コードのサポートを必要としない全ての QMK キーコードをサポートします。キーボードのメンテナは独自のカスタムテンプレートを提供して、より多くの機能を実現することができます。 + +## アプリケーション開発者 + +もしあなたがアプリケーションでこの API を使うことに興味があるアプリケーション開発者であれば、[API の使用](ja/api_docs.md) に行くべきです。 + +## キーボードのメンテナ + +もし QMK Compiler API でのあなたのキーボードのサポートを強化したい場合は、[キーボードサポート](ja/reference_configurator_support.md) の節に行くべきです。 + +## バックエンド開発者 + +もし API 自体に取り組むことに興味がある場合は、[開発環境](ja/api_development_environment.md)のセットアップから始め、それから [API のハッキング](ja/api_development_overview.md) を調べるべきです。 diff --git a/ja/arm_debugging.md b/ja/arm_debugging.md new file mode 100644 index 00000000000..afb5c4e0e6a --- /dev/null +++ b/ja/arm_debugging.md @@ -0,0 +1,92 @@ +# Eclipse を使った ARM デバッグ + + + +このページでは、SWD アダプタとオープンソース/フリーツールを使って ARM MCU をデバッグするためのセットアップ方法について説明します。このガイドでは、GNU MCU Eclipse IDE for C/C++ Developers および OpenOCD を必要な依存関係と一緒にインストールします。 + +このガイドは上級者向けであり、あなたのマシンで、MAKE フローを使って、ARM 互換キーボードをコンパイルできることを前提にしています。 + +## ソフトウェアのインストール + +ここでの主な目的は MCU Eclipse IDE を正しくマシンにインストールすることです。必要な手順は[この](https://gnu-mcu-eclipse.github.io/install/)インストールガイドから派生しています。 + +### xPack マネージャ + +このツールはソフトウェアパッケージマネージャであり、必要な依存関係を取得するために使われます。 + +XPM は Node.js を使って実行されるため、[ここ](https://nodejs.org/en/)から取得してください。インストール後に、ターミナルを開き `npm -v` と入力します。バージョン番号が返ってくるとインストールは成功です。 + +XPM のインストール手順は[ここ](https://www.npmjs.com/package/xpm)で見つけることができ、OS 固有のものです。ターミナルに `xpm --version` と入力すると、ソフトウェアのバージョンが返ってくるはずです。 + +### ARM ツールチェーン + +XPM を使うと、ARM ツールチェーンをとても簡単にインストールできます。`xpm install --global @xpack-dev-tools/arm-none-eabi-gcc` とコマンドを入力します。 + +### Windows ビルドツール + +Windows を使っている場合は、これをインストールする必要があります! + +`xpm install --global @gnu-mcu-eclipse/windows-build-tools` + +### プログラマ/デバッガドライバ + +プログラマのドライバをインストールします。このチュートリアルはほとんどどこでも入手できる ST-Link v2 を使って作成されました。 +ST-Link を持っている場合は、ドライバは[ここ](https://www.st.com/en/development-tools/stsw-link009.html)で見つけることができます。そうでない場合はツールの製造元にお問い合わせください。 + +### OpenOCD + +この依存関係により、SWD は GDB からアクセスでき、デバッグに不可欠です。`xpm install --global @xpack-dev-tools/openocd` を実行します。 + +### Java + +Java は Eclipse で必要とされるため、[ここ](https://www.oracle.com/technetwork/java/javase/downloads/index.html)からダウンロードしてください。 + +### GNU MCU Eclipse IDE + +最後に IDE をインストールする番です。[ここ](https://github.com/gnu-mcu-eclipse/org.eclipse.epp.packages/releases/)のリリースページから最新バージョンを取得します。 + +## Eclipse の設定 + +ダウンロードした Eclipse IDE を開きます。QMK ディレクトリをインポートするために、File -> Import -> C/C++ -> Existing Code as Makefile Project を選択します。Next を選択し、Browse を使用して QMK フォルダを選択します。tool-chain リストから ARM Cross GCC を選択し、Finish を選択します。 + +これで、左側に QMK フォルダが表示されます。右クリックして、Properties を選択します。左側で MCU を展開し、ARM Toolchains Paths を選択します。xPack を押して OK を押します。OpenOCD Path で同じことを繰り返し、Windows の場合は、Build Tools Path でも同じことを繰り返します。Apply and Close を選択します。 + +ここで、必要な MCU パッケージをインストールします。Window -> Perspective -> Open Perspective -> Other... -> Packs を選択して、Packs perspective に移動します。Packs タブの横にある黄色のリフレッシュ記号を選択します。これは様々な場所から MCU の定義を要求するため、時間が掛かります。一部のリンクが失敗した場合は、おそらく Ignore を選択できます。 + +これが終了すると、ビルドやデバッグする MCU を見つけることができるはずです。この例では、STM32F3 シリーズの MCU を使います。左側で、STMicroelectronics -> STM32F3 Series を選択します。中央のウィンドウに、pack が表示されます。右クリックし、Install を選択します。それが終了したら、Window -> Perspective -> Open Perspective -> Other... -> C/C++ を選択してデフォルトのパースペクティブに戻ることができます。 + +Eclipse に QMK をビルドしようとするデバイスを教える必要があります。QMK フォルダを右クリック -> Properties -> C/C++ Build -> Settings を選択します。Devices タブを選択し、Devices の下から MCU の適切な種類を選択します。私の例では、STM32F303CC です。 + +この間に、Build コマンドもセットアップしましょう。C/C++ Build を選択し、Behavior タブを選択します。Build コマンドのところで、`all` を必要な make コマンドに置き換えます。例えば、rev6 Planck の default キーマップの場合、これは `planck/rev6:default` になります。Apply and Close を選択します。 + +## ビルド + +全て正しくセットアップできていれば、ハンマーボタンを押すとファームウェアがビルドされ、.bin ファイルが出力されるはずです。 + +## デバッグ + +### デバッガの接続 + +ARM MCU は、クロック信号(SWCLK) とデータ信号(SWDIO) で構成される Single Wire Debug (SWD) プロトコルを使います。MCU を完全に操作するには、この2本のワイヤとグラウンドを接続するだけで十分です。ここでは、キーボードは USB を介して電力が供給されると想定しています。手動でリセットボタンを使えるため、RESET 信号は必要ありません。より高度なセットアップのために printf と scanf をホストに非同期にパイプする SWO 信号を使用できますが、私たちのセットアップでは無視します。 + +注意: SWCLK と SWDIO ピンがキーボードのマトリックスで使われていないことを確認してください。もし使われている場合は、一時的に他のピンに切り替えることができます。 + +### デバッガの設定 + +QMK フォルダを右クリックし、Debug As -> Debug Configurations... を選択します。ここで、GDB OpenOCD Debugging をダブルクリックします。Debugger タブを選択し、MCU に必要な設定を入力します。これを見つけるにはいじったりググったりする必要があるかもしれません。STM32F3 用のデフォルトスクリプトは `stm32f3discovery.cfg` と呼ばれます。OpenOCD に伝えるには、Config options で `-f board/stm32f3discovery.cfg` と入力します。 + +注意: 私の場合、この設定スクリプトはリセット操作を無効にするために編集が必要です。スクリプトの場所は、通常はパス `openocd/version/.content/scripts/board` の下の実際の実行可能フィールドの中で見つかります。ここで、私は `reset_config srst_only` を `reset_config none` に編集しました。 + +Apply and Close を選択します。 + +### デバッガの実行 + +キーボードをリセットしてください。 + +虫アイコンをクリックし、もし全てうまく行けば Debug パースペクティブに移動します。ここでは、main 関数の最初でプログラムカウンタが停止し、Play ボタンが押されるのを待ちます。全てのデバッガのほとんどの機能は Arm MCU で動作しますが、正確な詳細については Google があなたのお友達です! + + +ハッピーデバッギング! diff --git a/ja/breaking_changes.md b/ja/breaking_changes.md new file mode 100644 index 00000000000..0f7256e684d --- /dev/null +++ b/ja/breaking_changes.md @@ -0,0 +1,121 @@ +# Breaking changes/互換性を破る変更 + + + +このドキュメントは QMK の互換性を破る変更(Breaking change) のプロセスについて説明します。 +互換性を破る変更とは、互換性がなかったり潜在的な危険が生じるように QMK の動作を変える変更を指します。 +ユーザが QMK ツリーを更新しても自分のキーマップが壊れない事を確信できるように、これらの変更を制限します。(訳注:以後、原文のまま Breaking change を用語として使用します。) + +Breaking change ピリオドとは、危険な変更、または予想外の変更を QMK へ行なう PR をマージする時のことです。 +付随するテスト期間があるため、問題が起きることはまれか、有りえないと確信しています。 + +## 過去の Breaking change には何が含まれますか? + +* [2020年8月29日](ja/ChangeLog/20200829.md) +* [2020年5月30日](ja/ChangeLog/20200530.md) +* [2020年2月29日](ja/ChangeLog/20200229.md) +* [2019年8月30日](ja/ChangeLog/20190830.md) + +## 次の Breaking change はいつですか? + +次の Breaking change は2020年11月28日に予定されています。 + +### 重要な日付 + +* [x] 2020年 8月29日 - `develop` が作成されました。毎週リベースされます。 +* [ ] 2020年10月31日 - `develop` は新しいPRを取り込みません。 +* [ ] 2020年10月31日 - テスターの募集。 +* [ ] 2020年11月26日 - `master`がロックされ、PR はマージされません。 +* [ ] 2020年11月28日 - `develop` を `master` にマージします。 +* [ ] 2020年11月28日 - `master` のロックが解除されます。PR を再びマージすることができます。 + +## どのような変更が含まれますか? + +最新の Breaking change 候補を見るには、[`breaking_change` ラベル](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Abreaking_change+is%3Apr)を参照してください。 +現在から `develop` が閉じられるまでの間に新しい変更が追加される可能性があり、そのラベルが適用された PR はマージされることは保証されていません。 + +このラウンドに、あなたの Breaking change を含めたい場合は、`breaking_change` ラベルを持つ PR を作成し、`develop` が閉じる前に承認してもらう必要があります。 +`develop` が閉じた後は、新しい Breaking change は受け付けられません。 + +受け入れの基準: + +* PR が完了し、マージの準備ができている +* PR が ChangeLog を持つ + +# チェックリスト + +ここでは、Breaking change プロセスを実行する時に使用する様々なプロセスについて説明します。 + +## `master` から `develop` をリベースします + +これは `develop` が開いている間、毎週金曜日に実行されます。 + +プロセス: + +``` +cd qmk_firmware +git checkout master +git pull --ff-only +git checkout develop +git rebase master +git push --force +``` + +## `develop` ブランチの作成 + +以前の `develop` ブランチがマージされた直後に、これが発生します。 + +* `qmk_firmware` git commands + * [ ] `git checkout master` + * [ ] `git pull --ff-only` + * [ ] `git checkout -b develop` + * [ ] Edit `readme.md` + * [ ] これがテストブランチであることを上部に大きな通知で追加します。 + * [ ] このドキュメントへのリンクを含めます + * [ ] `git commit -m 'Branch point for Breaking Change'` + * [ ] `git tag breakpoint___
` + * [ ] `git tag ` # ブレーキング ポイント タグがバージョンの増分を混乱させないようにします + * [ ] `git push origin develop` + * [ ] `git push --tags` + +## マージの 4 週間前 + +* `develop` は新しい PR に対して閉じられ、現在の PR の修正のみがマージされる可能性があります。 +* テスターの呼び出しを投稿します + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## マージの 1 週間前 + +* master が < 2 日前> から <マージの日> まで閉じられることを発表します + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## マージの 2 日前 + +* master が 2 日間閉じられることを発表します + * [ ] Discord + * [ ] GitHub PR + * [ ] https://reddit.com/r/olkb + +## マージの日 + +* `qmk_firmware` git commands + * [ ] `git checkout develop` + * [ ] `git pull --ff-only` + * [ ] `git rebase origin/master` + * [ ] Edit `readme.md` + * [ ] `develop` についてのメモを削除 + * [ ] ChangeLog を 1 つのファイルにまとめます。 + * [ ] `git commit -m 'Merge point for Breaking Change'` + * [ ] `git push origin develop` +* GitHub Actions + * [ ] `develop`の PR を作成します + * [ ] travis がクリーンに戻ったことを確認します + * [ ] `develop` PR をマージします diff --git a/ja/breaking_changes_instructions.md b/ja/breaking_changes_instructions.md new file mode 100644 index 00000000000..69d17d73c5f --- /dev/null +++ b/ja/breaking_changes_instructions.md @@ -0,0 +1,51 @@ +# breaking changes/互換性を破る変更: プルリクエストにフラグが付けられた + + + +QMK のメンバーがあなたのプルリクエストに返信し、あなたの提出したものは Breaking change (互換性を破る変更) であると述べている場合があります。メンバーの判断では、あなたが提案した変更は QMK やその利用者にとってより大きな影響を持つと考えられます。 + +プルリクエストにフラグが立てられる原因となるものには、以下のようなものがあります: + +- **ユーザーのキーマップに対する編集** + ユーザーが自分のキーマップを QMK に提出した後、しばらくしてさらに更新してプルリクエストを開いたところ、それが `qmk/qmk_firmware` リポジトリで編集されていたためにマージできなかったことに気づくことがあるかもしれません。すべてのユーザーが Git や GitHub を使いこなせるわけではないので、ユーザー自身で問題を修正できないことに気づくかもしれません。 +- **期待される動作の変更** + QMK の動作を変更すると、既存の QMK 機能への変更を組み込んだ新しいファームウェアをフラッシュした場合、ユーザはハードウェアまたは QMK が壊れていると考え、希望する動作を復元する手段がないことに気付くことがあります。 +- **ユーザーのアクションを必要とする変更** + 変更には、ツールチェインを更新したり、Git で何らかのアクションを取るなど、ユーザーがアクションを行う必要がある場合もあります。 +- **精査が必要な変更** + 時には、投稿がプロジェクトとしての QMK に影響を与えることもあります。これは、著作権やライセンスの問題、コーディング規約、大規模な機能のオーバーホール、コミュニティによるより広範なテストを必要とする「リスクの高い」変更、あるいは全く別のものである可能性があります。 +- **エンドユーザーとのコミュニケーションを必要とする変更** + これには、将来の非推奨化への警告、時代遅れの慣習、その他伝えなければならないが上記のカテゴリのどれかに当てはまらないものが含まれます。 + +## 何をすればいいのか? + +提出したものが Breaking change だと判断された場合、手続きをスムーズに進めるためにできることがいくつかあります。 + +### PR を分割することを検討する + +あなたがコアコードを投稿していて、それが Breaking change プロセスを経る必要がある唯一の理由が、あなたの変更に合わせてキーマップを更新していることである場合、古いキーマップが機能し続けるような方法であなたの機能を投稿できるかどうかを検討してください。 +そののち、Breaking change プロセスを経て古いコードを削除する別の PR を提出してください。 + +### ChangeLog エントリの提供 + +Breaking change プロセスを経て提出する際には、変更ログのエントリを含めることを我々は要請します。 +エントリーは、あなたのプルリクエストが行う変更の短い要約としてください – [ここの各セクションは changelog として開始されました](ja/ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft")。 + +変更ログは `docs/ChangeLog/YYYYMMDD/PR####.md` に置いてください。 +ここで、`YYYYMMDD` は QMK の breaking change ブランチ – 通常は `develop` という名称 – が `master` ブランチにマージされる日付、`####` はプルリクエストの番号です。 + +ユーザー側でのアクションを必要とする場合、あなたの変更ログは、どのようなアクションを取らなければならないかをユーザーに指示するか、そのようなアクションを指示する場所にリンクする必要があります。 + +### 変更点を文書化する + +提出物の目的を理解し、それが必要とする可能性のある意味合いやアクションを理解することで、レビュープロセスをより簡単にすることができます。この目的のためには変更履歴で十分かもしれませんが、より広範囲の変更を行う場合には、変更履歴には不向きな詳細レベルが必要になるかもしれません。 + +あなたのプルリクエストにコメントしたり、質問やコメント、変更要求に対応したりすることは、非常にありがたいことです。 + +### 助けを求める + +あなたの提出物にフラグが立ったことで、あなたはびっくりしてしまったかもしれません。もし、あなた自身が脅されたり、圧倒されたりしていると感じたら、私たちに知らせてください。プルリクエストにコメントするか、[Discord で QMK チームに連絡を取ってください](https://discord.gg/Uq7gcHh)。 diff --git a/ja/cli.md b/ja/cli.md new file mode 100644 index 00000000000..9e8169a84e0 --- /dev/null +++ b/ja/cli.md @@ -0,0 +1,43 @@ +# QMK CLI :id=qmk-cli + + + +## 概要 :id=overview + +QMK CLI を使用すると QMK キーボードの構築と作業が簡単になります。QMK ファームウェアの取得とコンパイル、キーマップの作成などのようなタスクを簡素化し合理化するためのコマンドを多く提供します。 + +### 必要事項 :id=requirements + +QMK は Python 3.6 以上を必要とします。我々は必要事項の数を少なくしようとしていますが、[`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt) に列挙されているパッケージもインストールする必要があります。これらは QMK CLI をインストールするときに自動的にインストールされます。 + +### Homebrew を使ったインストール (macOS、いくつかの Linux) :id=install-using-homebrew + +[Homebrew](https://brew.sh) をインストールしている場合は、タップして QMK をインストールすることができます: + +``` +brew install qmk/qmk/qmk +export QMK_HOME='~/qmk_firmware' # オプション、`qmk_firmware` の場所を設定します +qmk setup # これは `qmk/qmk_firmware` をクローンし、オプションでビルド環境をセットアップします +``` + +### pip を使ってインストール :id=install-using-easy_install-or-pip + +上で列挙した中にあなたのシステムがない場合は、QMK を手動でインストールすることができます。最初に、python 3.6 (以降)をインストールしていて、pip をインストールしていることを確認してください。次に以下のコマンドを使って QMK をインストールします: + +``` +python3 -m pip install qmk +export QMK_HOME='~/qmk_firmware' # オプション、`qmk_firmware` の場所を設定します +qmk setup # これは `qmk/qmk_firmware` をクローンし、オプションでビルド環境をセットアップします +``` + +### 他のオペレーティングシステムのためのパッケージ :id=packaging-for-other-operating-systems + +より多くのオペレーティングシステム用に `qmk` パッケージを作成および保守する人を探しています。OS 用のパッケージを作成する場合は、以下のガイドラインに従ってください: + +* これらのガイドラインと矛盾する場合は、OS のベストプラクティスに従ってください + * 逸脱する場合は、理由をコメントに文章化してください。 +* virtualenv を使ってインストールしてください +* 環境変数 `QMK_HOME` を設定して、ファームウェアソースを `~/qmk_firmware` 以外のどこかにチェックアウトするようにユーザに指示してください。 diff --git a/ja/cli_commands.md b/ja/cli_commands.md new file mode 100644 index 00000000000..81cb03cfe5b --- /dev/null +++ b/ja/cli_commands.md @@ -0,0 +1,296 @@ +# QMK CLI コマンド + + + +# ユーザー用コマンド + +## `qmk compile` + +このコマンドにより、任意のディレクトリからファームウェアをコンパイルすることができます。 からエクスポートした JSON をコンパイルするか、リポジトリ内でキーマップをコンパイルするか、現在の作業ディレクトリでキーボードをコンパイルすることができます。 + +このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 + +**Configurator Exports での使い方**: + +``` +qmk compile +``` + +**キーマップでの使い方**: + +``` +qmk compile -kb -km +``` + +**キーボードディレクトリでの使い方**: + +default キーマップのあるキーボードディレクトリ、キーボードのキーマップディレクトリ、`--keymap ` で与えられるキーマップディレクトリにいなければなりません。 +``` +qmk compile +``` + +**指定したキーマップをサポートする全てのキーボードをビルドする場合の使い方**: + +``` +qmk compile -kb all -km +``` + +**例**: +``` +$ qmk config compile.keymap=default +$ cd ~/qmk_firmware/keyboards/planck/rev6 +$ qmk compile +Ψ Compiling keymap with make planck/rev6:default +... +``` +あるいはオプションのキーマップ引数を指定して + +``` +$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4 +$ qmk compile -km 66_iso +Ψ Compiling keymap with make clueboard/66/rev4:66_iso +... +``` +あるいはキーマップディレクトリで + +``` +$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak +$ qmk compile +Ψ Compiling keymap with make make gh60/satan:colemak +... +``` + +**レイアウトディレクトリでの使い方**: + +`qmk_firmware/layouts/` 以下のキーマップディレクトリにいなければなりません。 +``` +qmk compile -kb +``` + +**例**: +``` +$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi +$ qmk compile -kb dz60 +Ψ Compiling keymap with make dz60:mechmerlin-ansi +... +``` + +## `qmk flash` + +このコマンドは `qmk compile` に似ていますが、ブートローダを対象にすることもできます。ブートローダはオプションで、デフォルトでは `:flash` に設定されています。 +違うブートローダを指定するには、`-bl ` を使ってください。利用可能なブートローダの詳細については、[ファームウェアを書き込む](ja/flashing.md)を見てください。 + +このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 + +**Configurator Exports での使い方**: + +``` +qmk flash -bl +``` + +**キーマップでの使い方**: + +``` +qmk flash -kb -km -bl +``` + +**ブートローダの列挙** + +``` +qmk flash -b +``` + +## `qmk config` + +このコマンドにより QMK の挙動を設定することができます。完全な `qmk config` のドキュメントについては、[CLI 設定](ja/cli_configuration.md)を見てください。 + +**使用法**: + +``` +qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] +``` + +## `qmk doctor` + +このコマンドは環境を調査し、潜在的なビルドあるいは書き込みの問題について警告します。必要に応じてそれらの多くを修正できます。 + +**使用法**: + +``` +qmk doctor [-y] [-n] +``` + +**例**: + +環境に問題がないか確認し、それらを修正するよう促します: + + qmk doctor + +環境を確認し、見つかった問題を自動的に修正します: + + qmk doctor -y + +環境を確認し、問題のみをレポートします: + + qmk doctor -n + +## `qmk info` + +QMK のキーボードやキーマップに関する情報を表示します。キーボードに関する情報を取得したり、レイアウトを表示したり、基礎となるキーマトリックスを表示したり、JSON キーマップをきれいに印刷したりするのに使用できます。 + +**使用法**: + +``` +qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD] +``` + +このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 + +**例**: + +キーボードの基本情報を表示する: + + qmk info -kb planck/rev5 + +キーボードのマトリクスを表示する: + + qmk info -kb ergodox_ez -m + +キーボードの JSON キーマップを表示する: + + qmk info -kb clueboard/california -km default + +## `qmk json2c` + +QMK Configurator からエクスポートしたものから keymap.c を生成します。 + +**使用法**: + +``` +qmk json2c [-o OUTPUT] filename +``` + +## `qmk list-keyboards` + +このコマンドは現在 `qmk_firmware` で定義されている全てのキーボードを列挙します。 + +**使用法**: + +``` +qmk list-keyboards +``` + +## `qmk list-keymaps` + +このコマンドは指定されたキーボード(とリビジョン)の全てのキーマップを列挙します。 + +このコマンドはディレクトリを認識します。キーボードのディレクトリにいる場合、自動的に KEYBOARD を入力します。 + +**使用法**: + +``` +qmk list-keymaps -kb planck/ez +``` + +## `qmk new-keymap` + +このコマンドは、キーボードの既存のデフォルトのキーマップに基づいて新しいキーマップを作成します。 + +このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 + +**使用法**: + +``` +qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] +``` + +--- + +# 開発者用コマンド + +## `qmk cformat` + +このコマンドは clang-format を使って C コードを整形します。 + +引数無しで実行すると、変更された全てのコアコードを整形します。デフォルトでは `git diff` で `origin/master` をチェックし、ブランチは `-b ` を使って変更できます。 + +`-a` で全てのコアコードを整形するか、コマンドラインでファイル名を渡して特定のファイルに対して実行します。 + +**指定したファイルに対する使い方**: + +``` +qmk cformat [file1] [file2] [...] [fileN] +``` + +**全てのコアファイルに対する使い方**: + +``` +qmk cformat -a +``` + +**origin/master で変更されたファイルのみに対する使い方**: + +``` +qmk cformat +``` + +**branch_name で変更されたファイルのみに対する使い方**: + +``` +qmk cformat -b branch_name +``` + +## `qmk docs` + +このコマンドは、ドキュメントを参照または改善するために使うことができるローカル HTTP サーバを起動します。デフォルトのポートは 8936 です。 + +**使用法**: + +``` +qmk docs [-p PORT] +``` + +## `qmk kle2json` + +このコマンドにより、生の KLE データから QMK Configurator の JSON へ変換することができます。絶対パスあるいは現在のディレクトリ内のファイル名のいずれかを受け取ります。デフォルトでは、`info.json` が既に存在している場合は上書きしません。上書きするには、`-f` あるいは `--force` フラグを使ってください。 + +**使用法**: + +``` +qmk kle2json [-f] +``` + +**例**: + +``` +$ qmk kle2json kle.txt +☒ File info.json already exists, use -f or --force to overwrite. +``` + +``` +$ qmk kle2json -f kle.txt -f +Ψ Wrote out to info.json +``` + +## `qmk pyformat` + +このコマンドは `qmk_firmware` 内の python コードを整形します。 + +**使用法**: + +``` +qmk pyformat +``` + +## `qmk pytest` + +このコマンドは python のテストスィートを実行します。python コードに変更を加えた場合、これの実行が成功することを確認する必要があります。 + +**使用法**: + +``` +qmk pytest +``` diff --git a/ja/cli_configuration.md b/ja/cli_configuration.md new file mode 100644 index 00000000000..f4857a60294 --- /dev/null +++ b/ja/cli_configuration.md @@ -0,0 +1,126 @@ +# QMK CLI 設定 + + + +このドキュメントは `qmk config` がどのように動作するかを説明します。 + +# はじめに + +QMK CLI の設定はキーバリューシステムです。各キーはピリオドで区切られたサブコマンドと引数名で構成されます。これにより、設定キーと設定された引数の間で簡単かつ直接的な変換が可能になります。 + +## 簡単な例 + +例として、`qmk compile --keyboard clueboard/66/rev4 --keymap default` コマンドを見てみましょう。 + +設定から読み取ることができる2つのコマンドライン引数があります: + +* `compile.keyboard` +* `compile.keymap` + +これらを設定してみましょう: + +``` +$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default +compile.keyboard: None -> clueboard/66/rev4 +compile.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +これで、毎回キーボードとキーマップを設定することなく、`qmk compile` を実行することができます。 + +## ユーザデフォルトの設定 + +複数のコマンド間で設定を共有したい場合があります。例えば、いくつかのコマンドは引数 `--keyboard` を受け取ります。全てのコマンドでこの値を設定する代わりに、その引数を受け取る全てのコマンドで使われるユーザ値を設定することができます。 + +例: + +``` +$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default +user.keyboard: None -> clueboard/66/rev4 +user.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# CLI ドキュメント (`qmk config`) + +`qmk config` コマンドは基礎となる設定とやり取りするために使われます。引数無しで実行すると、現在の設定を表示します。引数が指定された場合、それらは設定トークンと見なされます。設定トークンは以下の形式の空白を含まない文字列です: + + [.][=] + +## 設定値の設定 + +設定キーに等号 (=) を入れることで、設定値を設定することができます。キーは常に完全な `
.` 形式である必要があります。 + +例: + +``` +$ qmk config default.keymap=default +default.keymap: None -> default +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## 設定値の読み込み + +設定全体、単一のキー、あるいはセクション全体の設定値を読み取ることができます。1つ以上の値を表示するために複数のキーを指定することができます。 + +### 全体の構成例 + + qmk config + +### セクション全体の例 + + qmk config compile + +### 単一キーの例 + + qmk config compile.keyboard + +### 複数キーの例 + + qmk config user compile.keyboard compile.keymap + +## 設定値の削除 + +設定値を特別な文字列 `None` に設定することで、設定値を削除することができます。 + +例: + +``` +$ qmk config default.keymap=None +default.keymap: default -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +## 複数の操作 + +複数の読み込みおよび書き込み操作を1つのコマンドに組み合わせることができます。それらは順番に実行および表示されます: + +``` +$ qmk config compile default.keymap=default compile.keymap=None +compile.keymap=skully +compile.keyboard=clueboard/66_hotswap/gen1 +default.keymap: None -> default +compile.keymap: skully -> None +Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' +``` + +# ユーザ設定オプション + +| キー | デフォルト値 | 説明 | +|-----|---------------|-------------| +| user.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | +| user.keymap | None | キーマップ名 (例: `default`) | +| user.name | None | ユーザの GitHub のユーザ名。 | + +# 全ての設定オプション + +| キー | デフォルト値 | 説明 | +|-----|---------------|-------------| +| compile.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | +| compile.keymap | None | キーマップ名 (例: `default`) | +| hello.name | None | 実行時の挨拶の名前 | +| new_keyboard.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | +| new_keyboard.keymap | None | キーマップ名 (例: `default`) | diff --git a/ja/cli_development.md b/ja/cli_development.md new file mode 100644 index 00000000000..47262213aea --- /dev/null +++ b/ja/cli_development.md @@ -0,0 +1,223 @@ +# QMK CLI 開発 + + + +このドキュメントは、新しい `qmk` サブコマンドを書きたい開発者に役立つ情報が含まれています。 + +# 概要 + +QMK CLI は git で有名になったサブコマンドパターンを使って動作します。メインの `qmk` スクリプトは単に環境をセットアップし、実行する正しいエントリポイントを選択するためにあります。各サブコマンドは、何らかのアクションを実行しシェルのリターンコード、または None を返すエントリーポイント (`@cli.subcommand()` で修飾されます)を備えた自己完結型のモジュールです。 + +## 開発者モード: + +キーボードを保守、あるいは QMK に貢献したい場合は、CLI の「開発者」モードを有効にすることができます: + +`qmk config user.developer=True` + +これにより利用可能な全てのサブコマンドが表示されます。 +**注意:** 追加で必要なものをインストールする必要があります: +```bash +python3 -m pip install -r requirements-dev.txt +``` + +# サブコマンド + +[MILC](https://github.com/clueboard/milc) は、`qmk` が引数の解析、設定、ログ、およびほかの多くの機能を処理するために使用する CLI フレームワークです。グルーコードを書くために時間を無駄にすることなく、ツールの作成に集中できます。 + +ローカル CLI 内のサブコマンドは、常に `qmk_firmware/lib/python/qmk/cli` で見つかります。 + +サブコマンドの例を見てみましょう。これは `lib/python/qmk/cli/hello.py` です: + +```python +"""QMK Python Hello World + +This is an example QMK CLI script. +""" +from milc import cli + + +@cli.argument('-n', '--name', default='World', help='Name to greet.') +@cli.subcommand('QMK Hello World.') +def hello(cli): + """Log a friendly greeting. + """ + cli.log.info('Hello, %s!', cli.config.hello.name) +``` + +最初に `milc` から `cli` をインポートします。これが、ユーザとやり取りをし、スクリプトの挙動を制御する方法です。`@cli.argument()` を使って、コマンドラインフラグ `--name` を定義します。これは、ユーザが設定できる `hello.name` (そして対応する `user.name`) という名前の設定変数も作成し、引数を指定する必要が無くなります。`cli.subcommand()` デコレータは、この関数をサブコマンドとして指定します。サブコマンドの名前は関数の名前から取られます。 + +関数の中に入ると、典型的な "Hello, World!" プログラムが見つかります。`cli.log` を使って、基礎となる [ロガーオブジェクト](https://docs.python.org/3.6/library/logging.html#logger-objects) にアクセスし、その挙動はユーザが制御できます。またユーザが指定した名前の値に `cli.config.hello.name` でアクセスします。`cli.config.hello.name` の値は、ユーザが指定した `--name` 引数を調べることで決定されます。指定されていない場合、`qmk.ini` 設定ファイルの中の値が使われ、どちらも指定されていない場合は `cli.argument()` デコレータで指定されたデフォルトが代用されます。 + +# ユーザとの対話処理 + +MILC と QMK CLI にはユーザとやり取りするための幾つかの便利なツールがあります。これらの標準ツールを使うと、テキストに色を付けて対話し易くし、ユーザはその情報をいつどのように表示および保存するかを制御することができます。 + +## テキストの表示 + +サブコマンド内でテキストを出力するための2つの主な方法があります- `cli.log` と `cli.echo()`。それらは似た方法で動作しますが、ほとんどの一般的な目的の出力には `cli.log.info()` を使うことをお勧めします。 + +特別なトークンを使用してテキストを色付けし、プログラムの出力を理解しやすくすることができます。以下の[テキストの色付け](#colorizing-text)を見てください。 + +これらの両方の方法は python の [printf 形式の文字列書式化](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting) を使った組み込みの文字列書式化をサポートします。テキスト文字列内で`%s` と `%d` のようなトークンを使い、引数で値を渡すことができます。例として、上記の Hello、World プログラムを見てください。 + +書式演算子 (`%`) を直接使わないでください、常に引数で値を渡します。 + +### ログ (`cli.log`) + +`cli.log` オブジェクトは[ロガーオブジェクト](https://docs.python.org/3.6/library/logging.html#logger-objects)へのアクセスを与えます。ログ出力を設定し、ユーザに各ログレベルの素敵な絵文字(またはターミナルが unicode をサポートしない場合はログレベル名)を表示します。このようにして、ユーザは何か問題が発生した時に最も重要なメッセージを一目で確認することができます。 + +デフォルトのログレベルは `INFO` です。ユーザが `qmk -v ` を実行すると、デフォルトのログレベルは `DEBUG` に設定されます。 + +| 関数 | 絵文字 | +|----------|-------| +| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` | +| cli.log.error | `{fg_red}☒{style_reset_all}` | +| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` | +| cli.log.info | `{fg_blue}Ψ{style_reset_all}` | +| cli.log.debug | `{fg_cyan}☐{style_reset_all}` | +| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` | + +### 出力 (`cli.echo`) + +場合によっては単にログシステムの外部でテキストを出力する必要があります。これは、固定データを出力したり、ログに記録してはいけない何かを書きだす場合に適しています。ほとんどの場合、`cli.echo` よりも `cli.log.info()` を選ぶべきです。 + +### テキストの色付け + +テキスト内に色トークンを含めることで、テキストの出力を色付けすることができます。情報を伝えるためではなく、強調するために色を使います。ユーザは色を無効にできることを覚えておいてください。色を無効にした場合でもサブコマンドは引き続き使えるようにしてください。 + +背景色を設定するのは、あなたがやっていることに不可欠ではない限り、通常は避けるべきです。ユーザは、ターミナルの色に関しては多くの好みを持つため、あなたは黒と白のどちらの背景に対してもうまく機能する色を選択する必要があることを覚えておいてください。 + +'fg' という接頭辞の付いた色は、前景(テキスト)色に影響します。'bg' という接頭辞の付いた色は、背景色に影響します。 + +| 色 | 背景 | 拡張背景 | 前景 | 拡張前景 | +|-------|------------|---------------------|------------|--------------------| +| 黒 | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} | +| 青 | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} | +| シアン | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} | +| 緑 | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} | +| マゼンタ | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} | +| 赤 | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} | +| 白 | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} | +| 黄 | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} | + +ANSI 出力の挙動を変更するために使うことができる制御シーケンスもあります。 + +| 制御シーケンス | 説明 | +|-------------------|-------------| +| {style_bright} | テキストを明るくする | +| {style_dim} | テキストを暗くする | +| {style_normal} | テキストを通常にする (`{style_bright}` または `{style_dim}` のどちらでもない) | +| {style_reset_all} | 全てのテキストの属性をデフォルトに再設定する(これは自動的に全ての文字列の最後に自動的に追加されます。) | +| {bg_reset} | 背景色をユーザのデフォルトに再設定します。 | +| {fg_reset} | 背景色をユーザのデフォルトに再設定します。 | + +# 引数と設定 + +QMK は引数の解析と設定の詳細をあなたの代わりに処理します。新しい引数を追加すると、サブコマンドの名前と引数の長い名前に基づいて設定ツリーに自動的に組み込まれます。属性形式のアクセス (`cli.config..`) あるいは辞書形式のアクセス (`cli.config['']['']`) を使って、`cli.config` 内のこの設定にアクセスすることができます。 + +内部では、QMK は [設定ファイルのパーサ](https://docs.python.org/3/library/configparser.html) を使って設定を格納します。これにより、人間が編集可能な方法で設定を表す簡単で分かり易い方法を提供します。この設定へのアクセスをラップして、設定ファイルのパーサーが通常持たない幾つかの機能を提供しています。 + +## 設定値の読み込み + +通常期待される全ての方法で `cli.config` とやり取りすることができます。例えば、`qmk compile` コマンドは `cli.config.compile.keyboard` からキーボード名を取得します。値がコマンドライン、環境変数あるいは設定ファイルからきたものであるかどうかを知る必要はありません。 + +繰り返しもサポートされます: + +``` +for section in cli.config: + for key in cli.config[section]: + cli.log.info('%s.%s: %s', section, key, cli.config[section][key]) +``` + +## 設定値の設定 + +通常の方法で設定値を設定することができます。 + +辞書形式: + +``` +cli.config['
'][''] = +``` + +属性形式: + +``` +cli.config.
. = +``` + +## 設定値の削除 + +通常の方法で設定値を削除することができます。 + +辞書形式: + +``` +del(cli.config['
']['']) +``` + +属性形式: + +``` +del(cli.config.
.) +``` + +## 設定ファイルの書き方 + +設定は変更しても書き出されません。ほとんどのコマンドでこれをする必要はありません。ユーザに `qmk config` を使って設定を慎重に変更させることをお勧めします。 + +設定を書き出すために `cli.save_config()` を使うことができます。 + +## 設定からの引数の除外 + +一部の引数は設定ファイルに反映すべきではありません。これらは引数を作成する時に `arg_only=True` を追加することで除外することができます。 + +例: + +``` +@cli.argument('-o', '--output', arg_only=True, help='File to write to') +@cli.argument('filename', arg_only=True, help='Configurator JSON file') +@cli.subcommand('Create a keymap.c from a QMK Configurator export.') +def json_keymap(cli): + pass +``` + +`cli.args` を使ってのみこれらの引数にアクセスすることができます。例えば: + +``` +cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output) +``` + +# テスト、リントおよびフォーマット + +nose2、flake8 および yapf を使ってコードをテスト、リントおよびフォーマットします。これらのテストを実行するために `pytest` と `pyformat` サブコマンドを使うことができます。 + +### テストとリント + + qmk pytest + +### フォーマット + + qmk pyformat + +## フォーマットの詳細 + +[yapf](https://github.com/google/yapf) を使ってコードを自動的にフォーマットします。フォーマットの設定は `setup.cfg` の `[yapf]` セクションにあります。 + +?> ヒント- 多くのエディタは yapf をプラグインとして使って、入力したコードを自動的にフォーマットすることができます。 + +## テストの詳細 + +テストは `lib/python/qmk/tests/` にあります。このディレクトリに単体テストと統合テストの両方があります。コードの単体テストと統合テストの両方を書いてほしいですが、一方のみ書く場合は統合テストを優先してください。 + +PR にテストの包括的なセットが含まれない場合は、次のようなコメントをコードに追加して、他の人が手助けできるようにしてください: + + # TODO(unassigned/): Write tests + +[nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) を使ってテストを実行します。テスト関数でできることの詳細については、nose2 のドキュメントを参照してください。 + +## リントの詳細 + +flake8 を使ってコードをリントします。PR を開く前に、コードは flake8 をパスしなければなりません。これは `qmk pytest` を実行するときにチェックされ、PR を登録したときに CI によってチェックされます。 diff --git a/ja/coding_conventions_c.md b/ja/coding_conventions_c.md new file mode 100644 index 00000000000..fccd44a3ae0 --- /dev/null +++ b/ja/coding_conventions_c.md @@ -0,0 +1,63 @@ +# コーディング規約 (C) + + + +私たちのスタイルのほとんどはかなり理解しやすいですが、現時点では完全に一貫しているわけではありません。変更箇所周辺のコードのスタイルと一致させる必要がありますが、そのコードに一貫性が無い場合や不明瞭な場合は以下のガイドラインに従ってください: + +* 4つのスペース (ソフトタブ) を使ってインデントします。 +* 修正版 One True Brace Style を使います。 + * 開き括弧: ブロックを開始する文と同じ行の最後 + * 閉じ括弧: ブロックを開始した文と同じ字下げ + * Else If: 行の先頭に閉じ括弧を置き、次の開き括弧を同じ行の最後に置きます。 + * 省略可能な括弧: 常に括弧を付け加えます。 + * 良い: if (condition) { return false; } + * 悪い: if (condition) return false; +* C 形式のコメントの使用を推奨します: `/* */` + * コメントを機能を説明するストーリーと考えて下さい。 + * 特定の決定がなされた理由を充分なコメントで説明してください。 + * 分かり切ったコメントは書かないでください。 + * 分かり切ったコメントであるか確信できない場合は、コメントを含めてください。 +* 一般的に、行を折り返さないで、必要なだけ長くすることができます。行を折り返すことを選択した場合は、76列を超えて折り返さないでください。 +* 古い形式のインクルードガード (`#ifndef THIS_FILE_H`、`#define THIS_FILE_H`、...、`#endif`) ではなく、ヘッダファイルの先頭で `#pragma once` を使います。 +* プリプロセッサ if の両方の形式を受け付けます: `#ifdef DEFINED` と `#if defined(DEFINED)` + * どちらがいいかわからない場合は、`#if defined(DEFINED)` 形式を使ってください。 + * 複数の条件 `#if` に移行する場合を除き、既存のコードを別のスタイルに変更しないでください。 +* プリプロセッサディレクティブをインデントする方法(あるいはするかどうか)を決定する時は、以下の事に留意してください: + * 一貫性よりも読みやすさが重要です。 + * ファイルの既存のスタイルに従ってください。ファイルのスタイルが混在している場合は、修正しようとしているセクションに適したスタイルに従ってください。 + * インデントする時は、ハッシュを行の先頭に置き、`#` と `if` の間に空白を追加します。`#` の後ろに4つスペースを入れて開始します。 + * 周りの C コードのインデントレベルに従うか、プリプロセッサのディレクティブに独自のインデントレベルを設定することができます。コードの意図を最もよく伝えるスタイルを選択してください。 + +わかりやすいように例を示します: + +```c +/* Enums for foo */ +enum foo_state { + FOO_BAR, + FOO_BAZ, +}; + +/* Returns a value */ +int foo(void) { + if (some_condition) { + return FOO_BAR; + } else { + return -1; + } +} +``` + +# clang-format を使った自動整形 + +[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) は LLVM の一部で、誰もが手動で整形するほど暇ではないため、コードを自動整形することができます。私たちは、上記のコーディング規約のほとんどを適用する設定ファイルを提供しています。空白と改行のみを変更するため、省略可能な括弧は自分で付け加えることを忘れないでください。 + +Windows で clang-format を入手するには [full LLVM インストーラ](http://llvm.org/builds/)を使い、Ubuntu では `sudo apt install clang-format` を使ってください。 + +コマンドラインから実行する場合、オプションとして `-style=file` を渡すと、QMK ルートディレクトリ内の .clang-format 設定ファイルを自動的に見つけます。 + +VSCode を使う場合は、標準の C/C++ プラグインが clang-format をサポートしますが、その他にも [独立した拡張機能](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat) があります。 + +幾つかのコード (LAYOUT マクロのような)が clang-format によって破壊されるため、これらのファイルで clang-format を実行しないか、整形したくないコードを `// clang-format off` と `// clang-format on` で囲みます。 diff --git a/ja/coding_conventions_python.md b/ja/coding_conventions_python.md new file mode 100644 index 00000000000..d8d4a31503a --- /dev/null +++ b/ja/coding_conventions_python.md @@ -0,0 +1,331 @@ +# コーディング規約 (Python) + + + +私たちのスタイルの大部分は PEP8 に従いますが、神経質にならないように幾つかのローカルな変更を加えています。 + +* サポートされる全てのプラットフォームとの互換性のために、Python 3.6 を対象にしています。 +* 4つのスペース (ソフトタブ) を使ってインデントします +* 充分なコメントを書くことを推奨します + * コメントを機能を説明するストーリーと考えて下さい + * 特定の決定がなされた理由を充分なコメントで説明してください。 + * 分かり切ったコメントは書かないでください + * 分かり切ったコメントであるか確信できない場合は、コメントを含めてください。 +* 全ての関数について、役に立つ docstring を必要とします。 +* 一般的に、行を折り返さないで、必要なだけ長くすることができます。行を折り返すことを選択した場合は、76列を超えて折り返さないでください。 +* 私たちの慣習の幾つかは、Python 使いでは無い人にコードベースをより身近にするために、python コミュニティに広まっているものとは競合しています。 + +# YAPF + +コードを整形するために [yapf](https://github.com/google/yapf) を使うことができます。[setup.cfg](setup.cfg) で設定を提供しています。 + +# インポート + +`import ...` や `from ... import ...` をいつ使うかについての厳密なルールはありません。理解しやすさと保守性が究極の目的です。 + +一般的に、コードを短く理解しやすくするためにモジュールから特定の関数とクラス名をインポートする方が望ましいです。これにより、名前が曖昧になることがあります。代わりにモジュールをインポートするようにします。互換性のあるモジュールをインポートする時を除いて、インポートする時は "as" キーワードを避けるべきです。 + +インポートは各モジュール1行にする必要があります。標準的な python ルールに従って、インポート文をシステム、サードパーティ、ローカルにグループ化します。 + +`from foo import *` を使わないでください。代わりにインポートしたいオブジェクトのリストを指定するか、モジュール全体をインポートします。 + +## インポートの例 + +良い: + +``` +from qmk import effects + +effects.echo() +``` + +悪い: + +``` +from qmk.effects import echo + +echo() # echoがどこから来たのかが不明瞭です +``` + +良い: + +``` +from qmk.keymap import compile_firmware + +compile_firmware() +``` + +良いですが、上の方がより良いです: + +``` +import qmk.keymap + +qmk.keymap.compile_firmware() +``` + +# 命令文 + +各行1文としてください。 + +可能な場合(例えば `if foo: bar`)でも、2つの文を1行にまとめないでください。 + +# 命名 + +`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`, `function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`, `function_parameter_name`, `local_var_name`. + +関数名、変数名 およびファイル名は説明的でなければなりません; 略語を避けます。特に、プロジェクト外の読み手に曖昧あるいは馴染みのない略語を使わず、単語内の文字を削除して略さないでください。 + +常に .py のファイル名の拡張子を使います。ダッシュを使わないでください。 + +## 避けるべき名前 + +* カウンタあるいはイテレータ以外の1文字の名前。try/except 文では例外の識別子として `e` を使うことができます。 +* パッケージ/モジュール名内のダッシュ (`-`) +* `__double_leading_and_trailing_underscore__` (2つのアンダースコアで始まる名前と終わる名前、Python で予約済み) + +# Docstring + +docstring の一貫性を維持するために、以下のガイドラインを設定しました。 + +* マークダウン(Markdown)形式の使用 +* 常に少なくとも1つの改行を含む3つのダブルクォートの docstring を使ってください: `"""\n"""` +* 最初の行は、関数が行うことの短い (70文字未満) 説明です。 +* docstring が更に必要な場合は、説明と残りの間に空白行を入れます。 +* 開始の3つのダブルクォートと同じインデントレベルでインデント行を始めます +* 以下で説明する形式を使って全ての関数の引数について記述します +* Args:、Returns: および Raises: が存在する場合、それらは docstring の最後の3つの要素で、それぞれ空白行で区切られなければなりません。 + +## 簡単な docstring の例 + +``` +def my_awesome_function(): + """1970 Jan 1 00:00 UTC からの秒数を返します。 + """ + return int(time.time()) +``` + +## 複雑な docstring の例 + +``` +def my_awesome_function(): + """1970 Jan 1 00:00 UTC からの秒数を返します。 + + この関数は常に整数の秒数を返します。 + """ + return int(time.time()) +``` + +## 関数の引数の docstring の例 + +``` +def my_awesome_function(start=None, offset=0): + """1970 Jan 1 00:00 UTC からの秒数を返します。 + + この関数は常に整数の秒数を返します。 + + + Args: + start + 1970 Jan 1 00:00 UTC の代わりの開始時間 + + offset + 最初の引数からこの秒数が引かれた答えを返します + + Returns: + 秒数を表す整数。 + + Raises: + ValueError + `start` あるいは `offset` が正の数ではない場合 + """ + if start < 0 or offset < 0: + raise ValueError('start and offset must be positive numbers.') + + if not start: + start = time.time() + + return int(start - offset) +``` + +# 例外 + +例外は例外的な状況を処理するために使われます。フローの制御のために使われるべきではありません。これは Python の「許しを請う」という規範からの逸脱です。例外をキャッチする場合、異常な状況を処理する必要があります。 + +何らかの理由で全ての例外のキャッチを使う場合は、cli.log を使って例外とスタックトレースを記録する必要があります。 + +try/except ブロックをできるだけ短くします。多数の try 文が必要な場合は、コードを再構成する必要があるかもしれません。 + +# タプル + +1項目のタプルを定義する場合、タプルを使用していることが明らかになるように、常に末尾のカンマを含めます。暗黙的な1項目のタプルのアンパックに頼らないでください。明確なリストを使う方が良いです。 + +これはよく使用される printf 形式の書式文字列を使う場合に、特に重要です。 + +# リストと辞書 + +シーケンス形式と末尾のカンマとを区別するように YAPF を設定しました。末尾のカンマが省略されると、YAPF はシーケンスを1つの行として整形します。末尾のカンマがある場合、YAPF はシーケンスを1行1項目で整形します。 + +一般的に1行が短い定義になるようにすべきです。読みやすさと保守性を向上させるために、後からではなく早めに複数の行を分割してください。 + +# 括弧 + +過度な括弧は避けますが、括弧を使ってコードを理解しやすくします。タプルを明示的に返すか、あるいは数式の一部である場合を除き、return 文で括弧を使わないでください。 + +# 書式文字列 + +一般的に printf 形式の書式文字列を用います。例: + +``` +name = 'World' +print('Hello, %s!' % (name,)) +``` + +このスタイルはログモジュールで使われており、私たちはそれを広範囲で利用しており、一貫性を保つために他の場所でも採用しています。これは、私たちの気まぐれな読者の大部分である C プログラマにもおなじみのスタイルです。 + +付属の CLI モジュールは、パーセント (%) 演算子を使わずにこれらを使うことをサポートしています。詳細は、`cli.echo()` と様々な `cli.log` 関数 (例えば、`cli.log.info()`) を見てください。 + +# 内包表記とジェネレータ表記 + +内包表記とジェネレータの自由な使用を推奨しますが、あまりに複雑にしないでください。複雑になる場合は、理解しやすい for ループで代替します。 + +# ラムダ + +使っても問題ありませんが、おそらく避けるべきです。内包表記とジェネレータを使えば、ラムダの必要性は以前ほど強くありません。 + +# 条件式 + +変数の割り当てでは問題ありませんが、そうでなければ避けるべきです。 + +条件式はコードに続く if 文です。例えば: + +``` +x = 1 if cond else 2 +``` + +一般にこれらを関数の引数、シーケンス項目などとして使用することはお勧めできません。見落としやすくなります。 + +# デフォルト引数 + +推奨されていますが、値は不変オブジェクトでなければなりません。 + +デフォルト値に引数リストを指定する場合は、その場で変更できないオブジェクトを指定するように常に注意してください。可変オブジェクトを使うと変更は呼び出しの間で持続しますが、これは通常あなたの望むものではありませんそれがあなたのやろうとしていることであっても、他の人にとっては混乱するもので理解を妨げます。 + +悪い: + +``` +def my_func(foo={}): + pass +``` + +良い: + +``` +def my_func(foo=None): + if not foo: + foo = {} +``` + +# プロパティ + +getter および setter 関数の代わりにプロパティを常に使います。 + +``` +class Foo(object): + def __init__(self): + self._bar = None + + @property + def bar(self): + return self._bar + + @bar.setter + def bar(self, bar): + self._bar = bar +``` + +# True/False の評価 + +一般的に、if 文で等価性を調べるのではなく、暗黙的な True/False 評価を行うべきです。 + +悪い: + +``` +if foo == True: + pass + +if bar == False: + pass +``` + +良い: + +``` +if foo: + pass + +if not bar: + pass +``` + +# デコレータ + +適切な時に使ってください。理解に役立つ時を除き、魔法の(ように見える技巧の)使いすぎは避けるようにしてください。 + +# スレッドとマルチプロセス + +避けるべきです。これが必要な場合は、私たちがコードをマージする前に十分な理由を述べる必要があります。 + +# 強力な機能 + +Python は非常に柔軟な言語で、独自のメタクラス、バイトコードへのアクセス、実行中コンパイル、動的な継承、オブジェクトの親の変更、インポートハック、リフレクション、システム内部の変更など、多くの素晴らしい機能を提供します。 + +これらを使わないでください。 + +パフォーマンスは私たちにとって重要な関心ごとではなく、コードのわかりやすさに関心があります。私たちは、コードベースを1日か2日しかいじっていない人が利用できるようにしたいです。これらの機能は一般的に理解のしやすさを犠牲にするため、より高速あるいはよりコンパクトなコードよりも、容易に理解できるコードの方が望ましいです。 + +一部の標準ライブラリモジュールはこれらの手法を使っており、これらのモジュールを利用しても問題ありません。ただし、それらを使う時には、読みやすさと理解のしやすさを忘れないでください。 + +# 型アノテーション付きコード + +今のところ型アノテーションシステムを使っていないため、コードにアノテーションをつけないようにしてください。将来的にはこれを再検討する可能性があります。 + +# 関数の長さ + +小さくて焦点のあった関数にしてください。 + +長い関数が時には適切であることを理解しているので、関数の長さには厳密な制限はありません。関数が約40行を超える場合は、プログラムの構造を損なわずに分割できるかどうかを検討してください。 + +今のところ長い関数が完全に機能するとしても、数か月でそれを変更する人が新しい挙動を追加するかもしれません。これにより見つけにくいバグが発生するかもしれません。関数を短くかつシンプルにすることで、他の人がコードを読んで修正しやすくします。 + +幾つかのコードで作業をすると、長く複雑な関数を見つけるかもしれません。既存コードを変更することを怖がらないでください: もし、難しいことが判明したり、エラーがデバッグしづらいとわかったり、いくつかの異なるコンテキストで一部を使いたいような関数を扱っている場合、関数を小さくてより扱いやすい単位に分割することを検討してください。 + +# FIXME + +FIXME をコードに残しても構いません。なぜでしょうか?このコードを文章化しないままにするよりも、少なくとも考え抜く必要がある(あるいは混乱している)コードの一部を文章化するように奨励する方が、このコードを文章化しないままにするよりも良いです。 + +全ての FIXME は以下のように書式化されるべきです: + +``` +FIXME(username): 何々機能が完了したらこのコードを再検討する。 +``` + +...username はあなたの GitHub のユーザ名です。 + +# テスト + +統合テストと単体テストの組み合わせを使ってコードが可能な限りバグが無いようにします。全てのテストは `lib/python/qmk/tests/` にあります。`qmk pytest` を使って全てのテストを実行することができます。 + +これを書いている時点では、テストは全く完全なものではありません。現在のテストを見て、テストされていない状況のための新しいテストケースを書くことは、コードベースに精通し、QMK に貢献するという両方の点で素晴らしい方法です。 + +## 統合テスト + +統合テストは `lib/python/qmk/tests/test_cli_commands.py` にあります。ここで実際に CLI コマンドが実行され、全体的な動作が検証されます。[`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) を使って各 CLI コマンドを起動し、正しく動作するかを判断するために出力とリターンコードの組み合わせを使います。 + +## ユニットテスト + +`lib/python/qmk/tests/` 内の他の `test_*.py` ファイルはユニットテストを含みます。`lib/python/qmk/` 内の個々の関数のテストをここに書くことができます。一般的にこれらのファイルはモジュールに基づいて名前を付けられ、ドットはアンダースコアで置き換えられます。 + +これを書いている時点では、テストのためのモックを作っていません。これを変更する手伝いをしたい場合は、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) か [Discord の #cli に参加](https://discord.gg/heQPAgy)し、そこで会話を開始してください。 diff --git a/ja/compatible_microcontrollers.md b/ja/compatible_microcontrollers.md new file mode 100644 index 00000000000..56f4c029771 --- /dev/null +++ b/ja/compatible_microcontrollers.md @@ -0,0 +1,42 @@ +# 互換性のあるマイクロコントローラ + + + +QMK は十分な容量のフラッシュメモリを備えた USB 対応 AVR または ARM マイクロコントローラで実行されます - 一般的に 32kB 以上ですが、ほとんどの機能を無効にすると*ほんの* 16kB に詰め込むことができます。 + +## Atmel AVR + +以下は、USB スタックとして [LUFA](https://www.fourwalledcubicle.com/LUFA.php) を使います: + +* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) +* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) +* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) + +組み込みの USB インターフェースを持たない、いくつかの MCU は代わりに [V-USB](https://www.obdev.at/products/vusb/index.html) を使います: + +* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) +* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) +* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328) + +## ARM + +[ChibiOS](http://www.chibios.org) がサポートする USB 付きの ARM チップを使うこともできます。ほとんどのチップには十分な容量のフラッシュメモリがあります。動作するとわかっているのは: + +### STMicroelectronics (STM32) + +* [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html) +* [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html) +* [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html) + +### NXP (Kinetis) + +* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) +* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50) +* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72) + +## Atmel ATSAM + +Atmel の ATSAM マイクロコントローラの一つである、[Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop) で使用されている [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) には限定的なサポートがあります。 diff --git a/ja/config_options.md b/ja/config_options.md new file mode 100644 index 00000000000..67e973030df --- /dev/null +++ b/ja/config_options.md @@ -0,0 +1,409 @@ +# QMK の設定 + + + +QMK はほぼ無制限に設定可能です。可能なところはいかなるところでも、やりすぎな程、ユーザーがコードサイズを犠牲にしてでも彼らのキーボードをカスタマイズをすることを許しています。ただし、このレベルの柔軟性により設定が困難になります。 + +QMK には主に2種類の設定ファイルがあります- `config.h` と `rules.mk`。これらのファイルは QMK の様々なレベルに存在し、同じ種類の全てのファイルは最終的な設定を構築するために組み合わされます。最低の優先度から最高の優先度までのレベルは以下の通りです: + +* QMK デフォルト +* キーボード +* フォルダ (最大5レべルの深さ) +* キーマップ + +## QMK デフォルト + +QMK での全ての利用可能な設定にはデフォルトがあります。その設定がキーボード、フォルダ、あるいはキーマップレべルで設定されない場合、これが使用される設定です。 + +## キーボード + +このレベルにはキーボード全体に適用される設定オプションが含まれています。一部の設定は、リビジョンあるいはほとんどのキーマップで変更されません。他の設定はこのキーボードのデフォルトに過ぎず、フォルダあるいはキーマップによって上書きされる可能性があります。 + +## フォルダ + +一部のキーボードには、異なるハードウェア構成のためのフォルダとサブフォルダがあります。ほとんどのキーボードは深さ1のフォルダのみですが、QMK は最大深さ5のフォルダの構造をサポートします。各フォルダは、最終的な設定に組み込まれる独自の `config.h` と `rules.mk` ファイルを持つことができます。 + +## キーマップ + +このレベルには特定のキーマップのための全てのオプションが含まれています。以前の定義を上書きしたい場合は、`#undef ` を使って定義を解除し、エラー無しで再定義することができます。 + +# `config.h` ファイル + +これは最初に include されるものの 1 つである C ヘッダファイルで、プロジェクト全体(もし含まれる場合)にわたって持続します。多くの変数をここで設定し、他の場所からアクセスすることができます。`config.h` ファイルでは、以下のもの以外の、他の `config.h` ファイルやその他のファイルの include をしないでください: + + #include "config_common.h" + + +## ハードウェアオプション +* `#define VENDOR_ID 0x1234` + * VID を定義します。ほとんどの DIY プロジェクトにおいて、任意のものを定義できます +* `#define PRODUCT_ID 0x5678` + * PID を定義します。ほとんどの DIY プロジェクトでは、任意のものを定義できます +* `#define DEVICE_VER 0` + * デバイスのバージョンを定義します (多くの場合リビジョンに使われます) +* `#define MANUFACTURER Me` + * 一般的に、誰もしくはどのブランドがボードを作成したか +* `#define PRODUCT Board` + * キーボードの名前 +* `#define MATRIX_ROWS 5` + * キーボードのマトリックスの行の数 +* `#define MATRIX_COLS 15` + * キーボードのマトリックスの列の数 +* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }` + * 行のピン、上から下へ +* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }` + * 列のピン、左から右へ +* `#define MATRIX_IO_DELAY 30` + * マトリックスピン状態の変更と値の読み取り間のマイクロ秒単位の遅延 +* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }` + * 参考として、キーボードで使われていないピン +* `#define MATRIX_HAS_GHOST` + * マトリックスにゴーストがあるか(ありそうにないか)定義します +* `#define DIODE_DIRECTION COL2ROW` + * COL2ROW あるいは ROW2COL - マトリックスがどのように設定されているか。COL2ROW は、スイッチとロウ(行)ラインの間にダイオードが黒い印をロウ(行)ラインに向けて置いてあることを意味します。 +* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` + * ロウ(行)ラインとカラム(列)ラインにマップされているピンを左から右に。各スイッチが個別のピンとグラウンドに接続されているマトリックスを定義します。 +* `#define AUDIO_VOICES` + * (循環させるために)代替音声を有効にします +* `#define C4_AUDIO` + * ピン C4 のオーディオを有効にします +* `#define C5_AUDIO` + * ピン C5 のオーディオを有効にします +* `#define C6_AUDIO` + * ピン C6 のオーディオを有効にします +* `#define B5_AUDIO` + * ピン B5 のオーディオを有効にします (C[4-6]\_AUDIO の1つとともに B[5-7]\_AUDIO の1つが有効にされている場合、疑似ステレオが有効にされます) +* `#define B6_AUDIO` + * ピン B6 のオーディオを有効にします (C[4-6]\_AUDIO の1つとともに B[5-7]\_AUDIO の1つが有効にされている場合、疑似ステレオが有効にされます) +* `#define B7_AUDIO` + * ピン B7 のオーディオを有効にします (C[4-6]\_AUDIO の1つとともに B[5-7]\_AUDIO の1つが有効にされている場合、疑似ステレオが有効にされます) +* `#define BACKLIGHT_PIN B7` + * バックライトのピン +* `#define BACKLIGHT_LEVELS 3` + * バックライトのレベル数 (off を除いて最大31) +* `#define BACKLIGHT_BREATHING` + * バックライトのブレスを有効にします +* `#define BREATHING_PERIOD 6` + * 1つのバックライトの "ブレス" の長さの秒数 +* `#define DEBOUNCE 5` + * ピンの値を読み取る時の遅延 (5がデフォルト) +* `#define LOCKING_SUPPORT_ENABLE` + * メカニカルロックのサポート。キーマップで KC_LCAP、 KC_LNUM そして KC_LSCR を使えるようにします +* `#define LOCKING_RESYNC_ENABLE` + * キーボードの LED の状態をスイッチの状態と一致させ続けようとします +* `#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)` + * マジックコマンドの使用を可能にするキーの組み合わせ (デバッグに便利です) +* `#define USB_MAX_POWER_CONSUMPTION 500` + * デバイスの USB 経由の最大電力(mA) を設定します (デフォルト: 500) +* `#define USB_POLLING_INTERVAL_MS 10` + * キーボード、マウス および 共有 (NKRO/メディアキー) インタフェースのための USB ポーリングレートをミリ秒で設定します +* `#define F_SCL 100000L` + * I2C を使用するキーボードのための I2C クロックレート速度を設定します。デフォルトは `400000L` ですが、`split_common` を使っているキーボードは別でデフォルトは `100000L` です。 + +## 無効にできる機能 + +これらのオプションを定義すると、関連する機能が無効になり、コードサイズを節約できます。 + +* `#define NO_DEBUG` + * デバッグを無効にします +* `#define NO_PRINT` + * hid_listen を使った出力やデバッグを無効にします +* `#define NO_ACTION_LAYER` + * レイヤーを無効にします +* `#define NO_ACTION_TAPPING` + * タップダンスと他のタップ機能を無効にします +* `#define NO_ACTION_ONESHOT` + * ワンショットモディファイアを無効にします +* `#define NO_ACTION_MACRO` + * `MACRO()`、`action_get_macro()` _(非推奨)_ を使う古い形式のマクロ処理を無効にします +* `#define NO_ACTION_FUNCTION` + * `fn_actions`、`action_function()` _(非推奨)_ を使う古い形式の関数処理を無効にします + +## 有効にできる機能 + +これらのオプションを定義すると、関連する機能が有効になり、コードサイズが大きくなるかもしれません。 + +* `#define FORCE_NKRO` + * NKRO をデフォルトでオンにする必要があります。これにより EEPROM の設定に関係なく、キーボードの起動時に NKRO が強制的にオンになります。NKRO は引き続きオフにできますが、キーボードを再起動すると再びオンになります。 +* `#define STRICT_LAYER_RELEASE` + * キーリリースがどのレイヤーから来たのかを覚えるのではなく、現在のレイヤースタックを使って強制的に評価されるようにします (高度なケースに使われます) + +## 設定可能な挙動 + +* `#define TAPPING_TERM 200` + * タップがホールドになるまでの時間。500以上に設定された場合、タップ期間中にタップされたキーもホールドになります。(訳注: PERMISSIVE_HOLDも参照) +* `#define TAPPING_TERM_PER_KEY` + * キーごとの `TAPPING_TERM` 設定の処理を有効にします +* `#define RETRO_TAPPING` + * 押下とリリースの間に他のキーによる中断がなければ、TAPPING_TERM の後であってもとにかくタップします + * 詳細は [Retro Tapping](ja/tap_hold.md#retro-tapping) を見てください +* `#define TAPPING_TOGGLE 2` + * トグルを引き起こす前のタップ数 +* `#define PERMISSIVE_HOLD` + * `TAPPING_TERM` にヒットしていなくても、リリースする前に別のキーが押されると、タップとホールドキーがホールドを引き起こします + * 詳細は [Permissive Hold](ja/tap_hold.md#permissive-hold) を見てください +* `#define PERMISSIVE_HOLD_PER_KEY` + * キーごとの `PERMISSIVE_HOLD` 設定の処理を有効にします +* `#define IGNORE_MOD_TAP_INTERRUPT` + * 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします + * 詳細は [Ignore Mod Tap Interrupt](ja/tap_hold.md#ignore-mod-tap-interrupt) を見てください +* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY` + * キーごとの `IGNORE_MOD_TAP_INTERRUPT` 設定の処理を有効にします +* `#define TAPPING_FORCE_HOLD` + * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします + * [Tapping Force Hold](ja/tap_hold.md#tapping-force-hold)を見てください + * タップトグル機能を無効にします (`TT` あるいは One Shot Tap Toggle) +* `#define TAPPING_FORCE_HOLD_PER_KEY` + * キーごとの `TAPPING_FORCE_HOLD` 設定処理を有効にします。 +* `#define LEADER_TIMEOUT 300` + * リーダーキーがタイムアウトするまでの時間 + * タイムアウトする前にシーケンスを終了できない場合は、タイムアウトの設定を増やす必要があるかもしれません。あるいは、`LEADER_PER_KEY_TIMING` オプションを有効にすると良いでしょう。これは各キーがタップされた後でタイムアウトを再設定します。 +* `#define LEADER_PER_KEY_TIMING` + * 全体では無く各キーを押すたびに実行されるリーダーキーコードのタイマーを設定します +* `#define LEADER_KEY_STRICT_KEY_PROCESSING` + * Mod-Tap および Layer-Tap キーコードのためのキーコードフィルタリングを無効にします。例えば、これを有効にすると、`KC_A` を使いたい場合は `MT(MOD_CTL, KC_A)` を指定する必要があります。 +* `#define ONESHOT_TIMEOUT 300` + * ワンショットがタイムアウトするまでの時間 +* `#define ONESHOT_TAP_TOGGLE 2` + * ワンショットトグルが引き起こされるまでのタップ数 +* `#define QMK_KEYS_PER_SCAN 4` + * 走査ごとに1つ以上のキーを送信できるようにします。デフォルトでは、走査ごとに `process_record()` 経由で1つのキーイベントのみが送信されます。これはほとんどのタイピングにほとんど影響しませんが、多くのコードを入力しているか、走査レートが最初から遅い場合、キーイベントの処理に多少の遅延が生じる可能性があります。それぞれのプレスとリリースは別のイベントです。スキャン時間が 1ms 程度のキーボードの場合、とても高速なタイピストでさえ、実際にキーボードから数 ms 以上の遅延を発生させるのに必要な 500 キーストロークを1秒間に生成することはないでしょう。しかし、3~4ms の走査時間でコードを入力している場合はどうでしょうか?おそらくこれが必要です。 +* `#define COMBO_COUNT 2` + * [コンボ](ja/feature_combo.md)機能で使っているコンボの数にこれを設定します。 +* `#define COMBO_TERM 200` + * コンボキーが検出されるまでの時間。定義されていない場合は、デフォルトは `TAPPING_TERM` です。 +* `#define TAP_CODE_DELAY 100` + * 適切な登録に問題がある場合(VUSB ボードで珍しくない)、`register_code` と `unregister_code` の間の遅延を設定します。値はミリ秒です。 +* `#define TAP_HOLD_CAPS_DELAY 80` + * MacOS で特別な処理が行われるため、`KC_CAPSLOCK` を使う時にタップホールドキー (`LT`, `MT`) に遅延を設定します。この値はミリ秒で、定義されていない場合はデフォルトは80msです。macOS については、これを200以上に設定すると良いでしょう。 + +## RGB ライト設定 :id=rgb-light-configuration + +* `#define RGB_DI_PIN D7` + * WS2812 の DI 端子につなぐピン +* `#define RGBLIGHT_ANIMATIONS` + * RGB アニメーションを実行します +* `#define RGBLIGHT_LAYERS` + * オンとオフを切り替えることができる [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) を定義できます。現在のキーボードレイヤーまたは Caps Lock 状態を表示するのに最適です。 +* `#define RGBLIGHT_MAX_LAYERS` + * デフォルトは8です。もしさらに [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) が必要であれば、32まで拡張できます。 + * メモ: 最大値を大きくするとファームウェアサイズが大きくなり、分割キーボードで同期が遅くなります。 +* `#define RGBLIGHT_LAYER_BLINK` + * 指定されたミリ秒の間、ライトレイヤーを [点滅](ja/feature_rgblight.md?id=lighting-layer-blink) する機能を追加します(例えば、アクションを確認するため)。 +* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` + * 定義されている場合、RGB ライトがオフになっている場合でも [ライトレイヤー](ja/feature_rgblight?id=overriding-rgb-lighting-onoff-status) が表示されます。 +* `#define RGBLED_NUM 12` + * LED の数 +* `#define RGBLIGHT_SPLIT` + * 分割キーボードの左半分の RGB LED の出力を右半分の RGB LED の入力につなげるかわりに、それぞれの側で個別にコントローラの出力ピンが直接 RGB LED の入力に繋がっているときは、この定義が必要です。 +* `#define RGBLED_SPLIT { 6, 6 }` + * 分割キーボードの各半分の `RGB_DI_PIN` に直接配線されている接続されている LED の数 + * 最初の値は左半分の LED の数を示し、2番目の値は右半分です。 + * RGBLED_SPLIT が定義されている場合、RGBLIGHT_SPLIT は暗黙的に定義されます。 +* `#define RGBLIGHT_HUE_STEP 12` + * 色相の増減時のステップ単位 +* `#define RGBLIGHT_SAT_STEP 25` + * 彩度の増減時のステップ単位 +* `#define RGBLIGHT_VAL_STEP 12` + * 値(明度)の増減時のステップ単位 +* `#define RGBW` + * RGBW LED のサポートを有効にします + +## マウスキーオプション + +* `#define MOUSEKEY_INTERVAL 20` +* `#define MOUSEKEY_DELAY 0` +* `#define MOUSEKEY_TIME_TO_MAX 60` +* `#define MOUSEKEY_MAX_SPEED 7` +* `#define MOUSEKEY_WHEEL_DELAY 0` + +## 分割キーボードオプション + +分割キーボード固有のオプション。あなたの rules.mk に 'SPLIT_KEYBOARD = yes' が有ることを確認してください。 + +* `SPLIT_TRANSPORT = custom` + * 標準の分割通信ルーチンをカスタムのものに置き換えることができます。現在、ARM ベースの分割キーボードはこれを使わなければなりません。 + +### 左右の設定 + +1つ覚えておかなければならないことは、USB ポートが接続されている側が常にマスター側であるということです。USB に接続されていない側はスレーブです。 + +分割キーボードの左右を設定するには、幾つかの異なる方法があります (優先度の順にリストされています): + +1. `SPLIT_HAND_PIN` を設定します: 左右を決定するためにピンを読み込みます。ピンが high の場合、それが左側です。low であれば、その半分側が右側であると決定されます。 +2. `EE_HANDS` を設定し、各半分に `eeprom-lefthand.eep`/`eeprom-righthand.eep` を書き込みます + * DFU ブートローダを搭載したボードでは、これらの EEPROM ファイルを書き込むために `:dfu-split-left`/`:dfu-split-right` を使うことができます + * Caterina ブートローダを搭載したボード (標準的な Pro Micros など)では、`:avrdude-split-left`/`:avrdude-split-right` を使ってください + * ARM DFU ブートローダを搭載したボード (Proton C など)では、`:dfu-util-split-left`/`:dfu-util-split-right` を使ってください +3. `MASTER_RIGHT` を設定します: USBポートに差し込まれた側はマスター側で右側であると決定されます(デフォルトの逆) +4. デフォルト: USB ポートに差し込まれている側がマスター側であり、左側であると見なされます。スレーブ側は右側です + +#### 左右を定義します + +* `#define SPLIT_HAND_PIN B7` + * high/low ピンを使って左右を決定します。low = 右手、high = 左手。`B7` を使っているピンに置き換えます。これはオプションで、`SPLIT_HAND_PIN` が未定義のままである場合、EE_HANDS メソッドまたは標準の Let's Splitが使っている MASTER_LEFT / MASTER_RIGHT 定義をまだ使うことができます。 + +* `#define SPLIT_HAND_MATRIX_GRID ,` + * 左右はキーマトリックスのキースイッチが存在しない交点を使って決定されます。通常、この交点が短絡している(ローレベル)のときに左側と見なされます。もし `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT` が定義されている場合は、ローレベルの時に右側と決定されます。 + +* `#define EE_HANDS` (`SPLIT_HAND_PIN` と `SPLIT_HAND_MATRIX_GRID` が定義されていない場合のみ動作します) + * `eeprom-lefthand.eep`/`eeprom-righthand.eep` がそれぞれの半分に書き込まれた後で、EEPROM 内に格納されている左右の設定の値を読み込みます。 + +* `#define MASTER_RIGHT` + * マスター側が右側と定義されます。 + +### 他のオプション + +* `#define USE_I2C` + * Serial の代わりに I2C を使う場合 (デフォルトは serial) + +* `#define SOFT_SERIAL_PIN D0` + * serial を使う場合、これを定義します。`D0` あるいは `D1`,`D2`,`D3`,`E6`。 + +* `#define MATRIX_ROW_PINS_RIGHT { }` +* `#define MATRIX_COL_PINS_RIGHT { }` + * 右半分に左半分と異なるピン配置を指定したい場合は、`MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT` を定義することができます。現在のところ、`MATRIX_ROW_PINS` のサイズは `MATRIX_ROW_PINS_RIGHT` と同じでなければならず、列の定義も同様です。 + +* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` + * 右半分に左半分と異なる直接ピン配置を指定したい場合は、`DIRECT_PINS_RIGHT` を定義することができます。現在のところ、`DIRECT_PINS` のサイズは `DIRECT_PINS_RIGHT` と同じでなければなりません。 + +* `#define RGBLED_SPLIT { 6, 6 }` + * [RGB ライト設定](#rgb-light-configuration)を見てください。 + +* `#define SELECT_SOFT_SERIAL_SPEED ` (デフォルトの速度は1です) + * serial 通信を使う時のプロトコルの速度を設定します。 + * 速度: + * 0: 約 189kbps (実験目的のみ) + * 1: 約 137kbps (デフォルト) + * 2: 約 75kbps + * 3: 約 39kbps + * 4: 約 26kbps + * 5: 約 20kbps + +* `#define SPLIT_USB_DETECT` + * マスタ/スレーブを委任する時に(タイムアウト付きで) USB 接続を検出します + * ARM についてはデフォルトの挙動 + * AVR Teensy については必須 + +* `#define SPLIT_USB_TIMEOUT 2000` + * `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合の最大タイムアウト + +* `#define SPLIT_USB_TIMEOUT_POLL 10` + * `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合のポーリング頻度 + +# `rules.mk` ファイル + +これは、トップレベルの `Makefile` から include される [make](https://www.gnu.org/software/make/manual/make.html) ファイルです。これは特定の機能を有効または無効にするだけでなく、コンパイルする MCU に関する情報を設定するために使われます。 + +## ビルドオプション + +* `DEFAULT_FOLDER` + * キーボードに1つ以上のサブフォルダがある場合にデフォルトのフォルダを指定するために使われます。 +* `FIRMWARE_FORMAT` + * ビルドの後でルート `qmk_firmware` フォルダにコピーされる形式 (bin, hex) を定義します。 +* `SRC` + * コンパイル・リンクリストにファイルを追加するために使われます。 +* `LIB_SRC` + * コンパイル・リンクリストにライブラリとしてファイルを追加するために使われます。 + `LIB_SRC` で指定されたファイルは、`SRC` で指定されたファイルの後にリンクされます。 + 例えば、次のように指定した場合: + ``` + SRC += a.c + LIB_SRC += lib_b.c + SRC += c.c + LIB_SRC += lib_d.c + ``` + リンク順は以下の通りです。 + ``` + ... a.o c.o ... lib_b.a lib_d.a ... + ``` +* `LAYOUTS` + * このキーボードがサポートする[レイアウト](ja/feature_layouts.md)のリスト +* `LTO_ENABLE` + * キーボードをコンパイルする時に、Link Time Optimization (LTO) を有効にします。これは処理に時間が掛かりますが、コンパイルされたサイズを大幅に減らします (そして、ファームウェアが小さいため、追加の時間は分からないくらいです)。 +ただし、LTO が有効な場合、古い TMK のマクロと関数の機能が壊れるため、自動的にこれらの機能を無効にします。これは `NO_ACTION_MACRO` と `NO_ACTION_FUNCTION` を自動的に定義することで行われます。(メモ: これは QMK の [マクロ](ja/feature_macros.md) と [レイヤー](ja/feature_layers.md) には影響を与えません。) + +## AVR MCU オプション +* `MCU = atmega32u4` +* `F_CPU = 16000000` +* `ARCH = AVR8` +* `F_USB = $(F_CPU)` +* `OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT` +* `BOOTLOADER = atmel-dfu` と以下のオプション: + * `atmel-dfu` + * `lufa-dfu` + * `qmk-dfu` + * `halfkay` + * `caterina` + * `bootloadHID` + * `USBasp` + +## 機能オプション :id=feature-options + +これらを使って特定の機能のビルドを有効または無効にします。有効にすればするほどファームウェアが大きくなり、MCU には大きすぎるファームウェアを構築するリスクがあります。 + +* `BOOTMAGIC_ENABLE` + * 仮想 DIP スイッチ設定 +* `MOUSEKEY_ENABLE` + * マウスキー +* `EXTRAKEY_ENABLE` + * オーディオ制御とシステム制御 +* `CONSOLE_ENABLE` + * デバッグ用コンソール +* `COMMAND_ENABLE` + * デバッグ及び設定用のコマンド +* `COMBO_ENABLE` + * キーコンボ機能 +* `NKRO_ENABLE` + * USB N-キーロールオーバー - これが動作しない場合は、ここを見てください: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +* `AUDIO_ENABLE` + * オーディオサブシステムを有効にします。 +* `RGBLIGHT_ENABLE` + * キーボードアンダーライト機能を有効にします +* `LEADER_ENABLE` + * リーダーキーコードを有効にします +* `MIDI_ENABLE` + * MIDI 制御 +* `UNICODE_ENABLE` + * Unicode +* `BLUETOOTH` + * 現在のオプションは、AdafruitBLE、RN42 +* `SPLIT_KEYBOARD` + * 分割キーボード (let's split や bakingpy のキーボードのようなデュアル MCU) のサポートを有効にし、quantum/split_common にある全ての必要なファイルをインクルードします +* `CUSTOM_MATRIX` + * 標準マトリックス走査ルーチンを独自のものに置き換えることができます。 +* `DEBOUNCE_TYPE` + * 標準キーデバウンスルーチンを代替または独自のものに置き換えることができます。 +* `WAIT_FOR_USB` + * キーボードが起動する前に、USB 接続が確立されるのをキーボードに待機させます +* `NO_USB_STARTUP_CHECK` + * キーボードの起動後の usb サスペンドチェックを無効にします。通常、キーボードはタスクが実行される前にホストがウェイク アップするのを待ちます。分割キーボードは半分はウェイクアップコールを取得できませんが、マスタにコマンドを送信する必要があるため、役に立ちます。 + +## USB エンドポイントの制限 + +USB 経由でサービスを提供するために、QMK は USB エンドポイントを使う必要があります。 +これらは有限なリソースです: 各マイクロコントローラは特定の数しか持ちません。 +これは一緒に有効にできる機能を制限します。 +利用可能なエンドポイントを超えると、ビルドエラーをひきおこします。 + +以下の機能は個別のエンドポイントを必要とするかもしれません: + +* `MOUSEKEY_ENABLE` +* `EXTRAKEY_ENABLE` +* `CONSOLE_ENABLE` +* `NKRO_ENABLE` +* `MIDI_ENABLE` +* `RAW_ENABLE` +* `VIRTSER_ENABLE` + +エンドポイントの使用率を向上させるために、HID 機能を組み合わせて1つのエンドポイントを使うようにすることができます。 +デフォルトでは、`MOUSEKEY`、`EXTRAKEY` および `NKRO` が単一のエンドポイントに結合されます。 + +基本キーボード機能も、`KEYBOARD_SHARED_EP = yes` を設定することで同じエンドポイントに結合することができます。 +これによりもう1つのエンドポイントが解放されますが、一部の BIOS ではブートキーボードプロトコルの切り替えを実装しないため、キーボードが動作しなくなるかもしれません。 + +マウスの結合も、ブートマウス互換性を破壊します。 +この機能が必要な場合は、`MOUSE_SHARED_EP = no` を設定することで、マウスを結合しないようにすることができます。 diff --git a/ja/configurator_step_by_step.md b/ja/configurator_step_by_step.md new file mode 100644 index 00000000000..92be0f16a95 --- /dev/null +++ b/ja/configurator_step_by_step.md @@ -0,0 +1,67 @@ +# QMK Configurator: ステップ・バイ・ステップ + + + +このページでは、QMK Configurator でファームウェアを構築する手順を説明します。 + +## ステップ 1: キーボードを選ぶ + +ドロップダウンボックスをクリックして、キーマップを作成するキーボードを選択します。 + +?> **キーボードに複数のバージョンがある場合は、正しいバージョンを選択してください。** + +大事なことなのでもう一度言います。 + +!> **正しいバージョンを選択してください!** + +キーボードが QMK を搭載していると宣伝されていてもリストにない場合は、開発者がまだ作業中か、私たちがまだマージするきっかけがなかった可能性があります。 +アクティブな [プルリクエスト](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) がない場合、[qmk_firmware](https://github.com/qmk/qmk_firmware/issues)で報告して、その特定のキーボードのサポートをリクエストします。 +製作者自身の GitHub アカウントにある QMK 搭載キーボードもあります。 +それも再確認してください。 + +## ステップ2: キーボードのレイアウトを選択する + +作成したいと思うキーマップに最も近いレイアウトを選択します。一部のキーボードには、まだ十分なレイアウトや正しいレイアウトが定義されていません。これらは将来サポートされる予定です。 + +## ステップ3: キーマップの名前を決める + +お好みの名前をキーマップにつけます。 + +?> コンパイル時に問題が発生した場合は、もしかすると QMK ファームウェアリポジトリに既に同じ名前が存在しているのかもしれません。名前を変更してみてください。 + +## ステップ4: キーマップを定義する + +キーコードの入力は、3つの方法のいずれかで行います。 + +1. ドラッグ・アンド・ドロップ +2. レイアウト上の空の場所をクリックして、希望するキーコードをクリックします +3. レイアウト上の空の場所をクリックして、キーボードの物理キーを押します + +?> マウスをキーの上に置くと、そのキーコードの機能の短い説明文が出ます。より詳細な説明については以下を見てください: + +* [基本的なキーコードリファレンス](ja/keycodes_basic.md) +* [高度なキーコードリファレンス](ja/feature_advanced_keycodes.md) + +!> 選択したレイアウトが物理的なビルドと一致しない場合は、使用していないキーは空白のままにしておきます。どのキーが使用されているかわからない場合、例えば、バックスペースキーは1つだが `LAYOUT_all` には2つのキーがある場合は、同じキーコードを両方の場所に配置してください。 + +## ステップ5: 後日のためにキーマップを保存する + +キーマップに満足するか、または後で作業したい場合は、`Export Keymap' ボタンを押します。 +これでキーマップがあなたのコンピュータに保存されます。 +その後、`Import Keymap` ボタンを押すことで、この .json ファイルを後で読み込むことができます。 + +!> **注意:** このファイルは、kbfirmware.com またはその他のツールに使用される .json ファイルと同じ形式ではありません。これらのツールにこの .json を使用したり、QMK Configurator でこれらのツールの .json を使用しようとすると、問題が発生します。 + +## ステップ6: ファームウェアをコンパイルする + +緑色の `Compile` ボタンを押します。 + +コンパイルが完了すると、緑色の `Download Firmware` ボタンを押すことができます。 + +## 次のステップ: キーボードに書き込む(フラッシュする) + +[ファームウェアを書きこむ](ja/newbs_flashing.md) を参照してください。 diff --git a/ja/configurator_troubleshooting.md b/ja/configurator_troubleshooting.md new file mode 100644 index 00000000000..5979341c6e8 --- /dev/null +++ b/ja/configurator_troubleshooting.md @@ -0,0 +1,32 @@ +# Configurator トラブルシューティング + + + +## 私の .json ファイルが動きません + +.json ファイルが QMK Configurator で作ったものの場合、おめでとうございます。バグに遭遇しました。 [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) で報告してください。 + +そうでない場合は、... 他の .json ファイルを使用しないようにという、上に書いた注意書きを見逃してませんか? + +#### レイアウトに余分なスペースがありますか?どうすればいいですか? + +もしスペースバーが3つに分かれている場合は、全てスペースバーで埋めるのが最善の方法です。バックスペースや Shift キーについても同じことができます。 + +#### キーコードってなに? + +以下を見てください。 + +* [基本的なキーコードリファレンス](ja/keycodes_basic.md) +* [高度なキーコードリファレンス](ja/feature_advanced_keycodes.md) + +#### コンパイルできません + +キーマップの他のレイヤーを再確認して、おかしなキーが存在しないことを確認してください。 + +## 問題とバグ + +私たちは利用者の依頼やバグレポートを常に受け入れています。[qmk_configurator](https://github.com/qmk/qmk_configurator/issues) で報告してください。 diff --git a/ja/contributing.md b/ja/contributing.md new file mode 100644 index 00000000000..75cedf0b347 --- /dev/null +++ b/ja/contributing.md @@ -0,0 +1,173 @@ +# 貢献方法 + + + +👍🎉 まず、これを読み貢献する時間を作ってくれてありがとうございます!🎉👍 + +サードパーティの貢献は、QMK の成長と改善に役立ちます。プルリクエストと貢献プロセスを貢献者とメンテナの両方にとって便利で簡単なものにしたいです。この目的のために、大きな変更をせずにプルリクエストが受け入れられるように貢献者向けのガイドラインをまとめました。 + +* [プロジェクトの概要](#project-overview) +* [コーディング規約](#coding-conventions) +* [一般的なガイドライン](#general-guidelines) +* [行動規範は私にとって何を意味しますか?](#what-does-the-code-of-conduct-mean-for-me) + +## この全てを読みたくはありません!単純に質問があります! + +QMK について質問したい場合は、[OLKB Subreddit](https://reddit.com/r/olkb) あるいは [Discord](https://discord.gg/Uq7gcHh) ですることができます。 + +以下の事を覚えておいてください: + +* 誰かがあなたの質問に答えるのに数時間掛かるかもしれません。しばらくお待ちください! +* QMK に関わる全ての人が彼らの時間とエネルギーを提供しています。QMK に関する作業や質問への回答に対する報酬はありません。 +* できるだけ簡単に答えられるように質問してみてください。その方法が分からない場合は、以下に幾つかの良いガイドがあります: + * https://opensource.com/life/16/10/how-ask-technical-questions + * http://www.catb.org/esr/faqs/smart-questions.html + +# プロジェクトの概要 :id=project-overview + +QMK は主に C で書かれており、特定の機能と部品は C++ で書かれています。QMK は、キーボードの中の組み込みプロセッサ、特に AVR ([LUFA](http://www.fourwalledcubicle.com/LUFA.php)) と ARM ([ChibiOS](http://www.chibios.com)) を対象にしています。すでに Arduino プログラミングに精通している場合は、多くの概念と制限がおなじみのものです。QMK に貢献するには Arduino を使用した経験は必要ありません。 + + + +# どこで助けを得られますか? + +助けが必要であれば、[issue を開く](https://github.com/qmk/qmk_firmware/issues) か [Discord で会話する](https://discord.gg/Uq7gcHh)ことができます。 + +# どうやって貢献することができますか? + +以前にオープンソースに貢献したことはありませんか? QMK で貢献がどのように機能するかが疑問ですか? ここに簡単な説明があります! + +0. [GitHub](https://github.com) アカウントにサインアップします。 +1. 貢献するためのキーマップをまとめるか、解決に興味がある[問題を見つける](https://github.com/qmk/qmk_firmware/issues)、あるいは追加したい[機能](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)を見つけます。 +2. 問題に関連付けられているリポジトリをあなたの GitHub アカウントにフォークします。これは、`GitHub上のあなたのユーザー名/qmk_firmware` の下にリポジトリのコピーを持つことを意味します。 +3. `git clone https://github.com/GitHub上のあなたのユーザー名/repository-name.git` を使ってローカルマシンにリポジトリをクローンします。 +4. 新しい機能に取り組んでいる場合は、issue を開きこれから行う作業について話し合うことを検討してください。 +5. `git checkout -b branch-name-here` を使って修正用の新しいブランチを作成します。 +6. 解決しようとしている問題、あるいは追加したい機能について適切な変更を加えます。 +7. `git add insert-paths-of-changed-files-here` を使って変更されたファイルの内容を git がプロジェクトの状態を管理するために使用する "snapshot"、インデックスとしても知られている、に追加します。 +8. `git commit -m "Insert a short message of the changes made here"` を使って、説明的なメッセージとともにインデックスの内容を保存します。 +9. `git push origin branch-name-here` を使って GitHub 上のリポジトリに変更をプッシュします。 +10. プルリクエストを [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master) にサブミットします。 +11. 行われた変更の簡単な説明と、変更に関する問題またはバグ番号を使って、プルリクエストにタイトルを付けます。例えば、issue に "Added more log outputting to resolve #4352" のようなタイトルをつけることができます。 +12. プルリクエストの説明では、行った変更、行ったプルリクエストに存在すると思われる問題、およびメンテナに対する質問を説明します。プルリクエストが完ぺきではない場合(プルリクエストが無い場合)でも問題ありません。レビュワーが問題の修正と改善を手伝います。 +13. プルリクエストがメンテナによってレビューされるのを待ちます。 +14. レビューをしているメンテナが変更を推奨する場合は、プルリクエストに変更を加えます。 +15. プルリクエストがマージされた後で成功を祝います! + +# コーディング規約 :id=coding-conventions + +私たちのスタイルのほとんどは簡単に理解できます。C あるいは Python のいずれかに精通している場合は、ローカルスタイルにそれほど問題はないはずです。 + +* [コーディング規約 - C](ja/coding_conventions_c.md) +* [コーディング規約 - Python](ja/coding_conventions_python.md) + +# 一般的なガイドライン :id=general-guidelines + +QMK には幾つかの異なるタイプの変更があり、それぞれ異なるレベルの厳密さが必要です。どのような種類の変更を行っても、次のガイドラインに留意してください。 + +* PR を論理単位に分割します。例えば、2つの個別の機能をカバーする1つの PR を送信するのではなく、代わりに機能ごとに個別の PR をサブミットします。 +* コミットする前に、`git diff --check` を使って不要な空白を確認します。 +* コードの変更が実際にコンパイルされることを確認してください。 + * キーマップ: `make keyboard:your_new_keymap` がエラーを返さないことを確認してください。 + * キーボード: `make keyboard:all` がエラーを返さないことを確認してください。 + * コア: `make all` がエラーを返さないことを確認してください。 +* コミットメッセージがそれ自体で理解できることを確認してください。最初の行に短い説明(70文字以内)を入れ、2行目は空にし、3行目以降では必要に応じてコミットを詳細に説明する必要があります。例: + +``` +kerpleplork の fronzlebop を調整します + +kerpleplork はエラーコード 23 で連続的に失敗していました。根本的な原因は fronzlebop 設定で、これにより kerpleplork はN回の繰り返しごとにアクティブになります。 + +私が使用できるデバイスの限られた実験では、kerpleplork の混乱を避けるために 7 は十分高い値であることを示していますが、念のため ARM デバイスを持つ人たちからフィードバックを得たいです。 +``` + +!> **重要:** デフォルト以外のキーマップ、ユーザスペースおよびレイアウトのようなユーザコードへのバグ修正あるいは改善に貢献したい場合は、PR にコードの元の提出者にタグをつけてください。Git と GitHub のスキルレベルに関係なく、多くのユーザは知らないうちにコードが変更されることに混乱したりイライラしたりするかもしれません。 + +## ドキュメント + +ドキュメントは QMK への貢献を始める最も簡単な方法の1つです。ドキュメントが間違っているか不完全な場所を見つけ、これらを修正するのは簡単です!私たちもドキュメントを編集する人を非常に必要としています。編集するスキルがあるが、どこにどのように飛び乗ればいいのか分からない場合は、[助けをもとめて](#where-can-i-go-for-help)ください! + +全てのドキュメントは `qmk_firmware/docs` ディレクトリの中にあります。あるいは web ベースのワークフローを使いたい場合は、https://docs.qmk.fm/ の各ページの下部にある "Edit this page" リンクをクリックすることができます。 + +ドキュメントの中にコードの例を提供する場合は、ドキュメント内の他の場所で使用されている命名規則を順守してください。例えば、一貫性を保つために、`my_layers` あるいは `my_keycodes` として列挙型を標準化します: + +```c +enum my_layers { + _FIRST_LAYER, + _SECOND_LAYER +}; + +enum my_keycodes { + FIRST_LAYER = SAFE_RANGE, + SECOND_LAYER +}; +``` + +### ドキュメントのプレビュー :id=previewing-the-documentation + +開発環境をセットアップした場合は、プルリクエストを開く前に以下のコマンドを `qmk_firmware/` フォルダから実行することで、あなたの変更をプレビューすることができます: + + ./bin/qmk docs + +または、Python 3 のみがインストールされている場合: + + python3 -m http.server 8936 + +その後、ウェブブラウザで、`http://localhost:8936/` を表示します。 + +## キーマップ + +ほとんどの初めての QMK 貢献者は、個人のキーマップから始めます。キーマップの標準はかなりカジュアルなものにしようとしています(キーマップは結局のところ作成者の性格を反映しています)が、他の人があなたのキーマップを簡単に見つけて学ぶことができるように、これらのガイドラインに従うようにお願いします。 + +* [テンプレート](documentation_templates.md) を使って `readme.md` を書きます。 +* 全てのキーマップの PR は squash されるため、コミットがどのように squash されるかを気にする場合は、自分で行う必要があります。 +* キーマップの PR に機能をまとめないでください。最初に機能をサブミットし、次にキーマップのための2つ目の PR をサブミットします。 +* `Makefile` をキーマップフォルダに含めないでください(もう使われていません)。 +* ファイルヘッダの著作権を更新します (`%YOUR_NAME%` を探します) + +## キーボード + +キーボードは QMK の存在理由です。一部のキーボードはコミュニティによって管理されていますが、他のキーボードはそれぞれのキーボードを作成する責任者によって管理されています。`readme.md` を見るとそのキーボードを管理しているのが誰かが分かります。特定のキーボードに関する質問がある場合、[Issue を開いて](https://github.com/qmk/qmk_firmware/issues)質問にメンテナをタグ付けしてください。(訳注: タグ付け は [メンションする](https://help.github.com/ja/github/writing-on-github/basic-writing-and-formatting-syntax#mentioning-people-and-teams) という意味です。) + +また以下のガイドラインに従うことをお願いします: + +* [テンプレート](ja/documentation_templates.md) を使って `readme.md` を書きます。 +* コミットの数を適切に保ってください。そうでなければあなたの PR を squash します。 +* コア機能を新しいキーボードにまとめないでください。最初に機能をサブミットし、次にキーボード用に別の PR をサブミットしてください。 +* `.c`/`.h` ファイルにすぐ上の親フォルダに従って名前を付けます。例えば、`/keyboards///.[ch]` +* `Makefile` をキーボードフォルダに含めないでください(もう使われていません) +* ファイルヘッダの著作権を更新します (`%YOUR_NAME%` を探します) + +## Quantum/TMK コア + +新しい機能をビルドするために多くの作業を行う前に、最適な方法で実装していることを確認する必要があります。[QMK の理解](ja/understanding_qmk.md)を読むことで、QMK の基本的な理解を得ることができます。これはあなたを QMK のプログラムフローのツアーに連れて行きます。ここから、あなたのアイデアを実装するための最良の方法の感覚をつかむために、私たちと話す必要があります。これを行うには主に2つの方法があります: + +* [Discord でのチャット](https://discord.gg/Uq7gcHh) +* [Issue を開く](https://github.com/qmk/qmk_firmware/issues/new) + +機能とバグ修正の PR は全てのキーボードに影響します。また、私たちは QMK の再編も進めています。このため、実装が行われる前に特に重要な変更について議論することが特に重要です。最初に私たちと話をせずに PR を開いた場合、あなたの選択が私たちの計画した方向とうまく合わない場合は幾つかの大きな再作業を行う覚悟をしてください。 + +機能やバグの修正に取り組む時に留意すべき幾つかの事があります。 + +* **デフォルトで無効** - QMK がサポートするほとんどのチップでメモリがかなり制限されており、現在のキーマップが壊れていないことが重要です。ですので、あなたの機能をオフにするのではなく**オン**にするようにしてください。デフォルトでオンにすべき場合、あるいはコードのサイズを小さくする必要がある場合は、相談してください。 +* **サブミットする前にローカルでコンパイル** - これが明白であることを願っていますが、コンパイルする必要があります。私たちの Travis システムは全ての問題をキャッチしますが、結果が返ってくるのを待つ代わりに幾つかのキーボードをローカルでコンパイルする方が一般的に速いです。 +* **リビジョンと異なるチップベースを考慮** - 僅かに異なる設定、さらには異なるチップベースを可能にするリビジョンを持つキーボードが幾つかあります。ARM および AVR でサポートされる機能を作成する、あるいは動作しないプラットフォームでは自動的に無効化するようにしてください。 +* **機能の説明** - 新しいファイルあるいは既存のファイルの一部として、`docs/` の中に文章化します。文章化しないと、他の人はあなたの苦労から利益を得ることができません。 + +また以下のガイドラインに従うことをお願いします: + +* コミットの数を適切に保ってください。そうでなければあなたの PR を squash します。 +* キーボードあるいはキーマップをコアの変更にまとめないでください。コアの変更を最初にサブミットしてください。 +* 機能のための[ユニット テスト](ja/unit_testing.md)を書いてください。 +* 編集しているファイルのスタイルに従ってください。スタイルが明確でないか、スタイルが混在している場合は、上記の[コーディング規約](#coding-conventions)に準拠する必要があります。 + +## リファクタリング + +QMK で物事がどのようにレイアウトされるかについて明確なビジョンを維持するために、私たちはリファクタリングを詳細に計画し、変更をする協力者がいます。リファクタリングのアイデアあるいは提案がある場合は、[issue を開いてください](https://github.com/qmk/qmk_firmware/issues)。QMK を改善する方法についてお話ししたいと思います。 + +# 行動規範は私にとって何を意味しますか? :id=what-does-the-code-of-conduct-mean-for-me + +私たちの[行動規範](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md)は、身元に関係なくあなたがプロジェクトの全員を敬意と礼儀を持って扱う責任があることを意味します。あなたが行動規範に記載されている不適切な行動やコメントの被害者である場合は、私たちはあなたのためにここにおり、私たちのコードに従って虐待者が適切に懲戒されるように最善を尽くします。 diff --git a/ja/custom_matrix.md b/ja/custom_matrix.md new file mode 100644 index 00000000000..277fc658d3a --- /dev/null +++ b/ja/custom_matrix.md @@ -0,0 +1,114 @@ +# カスタムマトリックス + + + +QMKは、デフォルトのマトリックススキャンルーチンを独自のコードで部分的に入れ替えたり全部入れ替えたりしたりするメカニズムを提供します。 + +この機能を使用する理由は次のとおりです: + +* キーボードのスイッチと MCU ピンの間に追加のハードウェアがある場合 + * I/O マルチプレクサ + * ラインデコーダー +* 一般的ではないキースイッチマトリックス + * `COL2ROW` と `ROW2COL` の同時使用 + +## 前提条件 + +カスタムマトリックスの実装には、通常、追加のソースファイルのコンパイルが含まれます。 +一貫性を保つために、このソースファイルのファイル名は `matrix.c` とすることをお勧めします。 + +あなたのキーボードディレクトリに新しいファイルを追加します: +```text +keyboards//matrix.c +``` + +そして、新しいファイルのコンパイルを指定するため、以下を `rules.mk` に追加します +```make +SRC += matrix.c +``` + +## マトリックスコードの部分置き換え :id=lite + +カスタムマトリックスを実装する際、定型コードを書かなくてすむように、さまざまなスキャン関数のデフォルト実装を提供しています。 + +設定するには、以下を `rules.mk` に追加します: +```make +CUSTOM_MATRIX = lite +``` + +そして、キーボードディレクトリの `matrix.c` ファイルに次の関数を実装します。 + +```c +void matrix_init_custom(void) { + // TODO: ここでハードウェアの初期化をする +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + bool matrix_has_changed = false; + + // TODO: ここで、マトリックススキャンを行なう + + return matrix_has_changed; +} +``` + +## マトリックスコードの全面置き換え + +スキャンルーチンをさらに変更する必要がある場合は、完全なスキャンルーチンを実装することを選択できます。 + +設定するには、以下を `rules.mk` に追加します: +```make +CUSTOM_MATRIX = yes +``` + +そして、キーボードディレクトリの `matrix.c` ファイルに次の関数を実装します。 + +```c +matrix_row_t matrix_get_row(uint8_t row) { + // TODO: 要求された行データを返します +} + +void matrix_print(void) { + // TODO: printf() を使って現在のマトリックスの状態をコンソールにダンプします +} + +void matrix_init(void) { + // TODO: ここでハードウェアとグローバルマトリックスの状態を初期化します + + // ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを初期化します + debounce_init(MATRIX_ROWS); + + // 正しいキーボード動作のためにこれを呼び出す*必要があります* + matrix_init_quantum(); +} + +uint8_t matrix_scan(void) { + bool matrix_has_changed = false; + + // TODO: ここにマトリックススキャンルーチンを追加します + + // ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを使用します + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + + // 正しいキーボード動作のためにこれを呼び出す*必要があります* + matrix_scan_quantum(); + + return matrix_has_changed; +} +``` + +また、次のコールバックのデフォルトも提供します。 + +```c +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } + +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } + +__attribute__((weak)) void matrix_init_user(void) {} + +__attribute__((weak)) void matrix_scan_user(void) {} +``` diff --git a/ja/custom_quantum_functions.md b/ja/custom_quantum_functions.md new file mode 100644 index 00000000000..952b5d8a87e --- /dev/null +++ b/ja/custom_quantum_functions.md @@ -0,0 +1,495 @@ +# キーボードの挙動をカスタマイズする方法 + + + +多くの人にとって、カスタムキーボードはボタンの押下をコンピュータに送信するだけではありません。単純なボタンの押下やマクロよりも複雑なことを実行できるようにしたいでしょう。QMK にはコードを挿入したり、機能を上書きしたり、様々な状況でキーボードの挙動をカスタマイズできるフックがあります。 + +このページでは、QMK に関する特別な知識は想定していませんが、[QMK の理解](ja/understanding_qmk.md)を読むとより根本的なレベルで何が起きているかを理解するのに役立ちます。 + +## コア、キーボード、キーマップ階層 :id=a-word-on-core-vs-keyboards-vs-keymap + +私たちは QMK を階層として構造化しました: + +* コア (`_quantum`) + * キーボード/リビジョン (`_kb`) + * キーマップ (`_user`) + +以下で説明される各関数は `_kb()` サフィックスあるいは `_user()` サフィックスを使って定義することができます。`_kb()` サフィックスはキーボード/リビジョンレベルで使うことを意図しており、一方で `_user()` サフィックスはキーマップレベルで使われるべきです。 + +キーボード/リビジョンレベルで関数を定義する場合、`_kb()` は他の何かを実行する前に `_user()` を呼び出すよう実装することが重要です。そうでなければ、キーマップレベル関数は呼ばれないでしょう。 + +# カスタムキーコード + +最も一般的なタスクは、既存のキーコードの挙動を変更するか、新しいキーコードを作成することです。コードの観点からは、それぞれの仕組みは非常に似ています。 + +## 新しいキーコードの定義 + +独自のカスタムキーコードを作成する最初のステップは、それらを列挙することです。これは、カスタムキーコードに名前を付け、そのキーコードにユニークな番号を割り当てることの両方を意味します。QMK は、カスタムキーコードを固定範囲の番号に制限するのではなく、`SAFE_RANGE` マクロを提供します。カスタムキーコードを列挙する時に `SAFE_RANGE` を使うと、ユニークな番号を取得することが保証されます。 + + +これは2つのキーコードを列挙する例です。このブロックを `keymap.c` に追加した後で、キーマップの中で `FOO` と `BAR` を使うことができます。 + +```c +enum my_keycodes { + FOO = SAFE_RANGE, + BAR +}; +``` + +## 任意のキーコードの挙動のプログラミング :id=programming-the-behavior-of-any-keycode + +既存のキーの挙動を上書きしたい場合、あるいは新しいキーについて挙動を定義する場合、`process_record_kb()` および `process_record_user()` 関数を使うべきです。これらは実際のキーイベントが処理される前のキー処理中に QMK によって呼び出されます。これらの関数が `true` を返す場合、QMK はキーコードを通常通りに処理します。これは、キーを置き換えるのではなく、キーの機能を拡張するのに便利です。これらの関数が `false` を返す場合、QMK は通常のキー処理をスキップし、必要なキーのアップまたはダウンイベントを送信するのかはユーザ次第です。 + +これらの関数はキーが押されるか放されるたびに呼び出されます。 + +### `process_record_user()` の実装例 + +この例は2つの事を行います。`FOO` と呼ばれるカスタムキーコードの挙動を定義し、Enter キーが押されるたびに音を再生します。 + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // 押された時に何かをします + } else { + // 放された時に何かをします + } + return false; // このキーの以降の処理をスキップします + case KC_ENTER: + // enter が押された時に音を再生します + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // QMK に enter のプレスまたはリリースイベントを送信させます + default: + return true; // 他の全てのキーコードを通常通りに処理します + } +} +``` + +### `process_record_*` 関数のドキュメント + +* キーボード/リビジョン: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* キーマップ: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` + +`keycode` 引数はキーマップで定義されているものです。例えば `MO(1)`、`KC_L` など。これらのイベントを処理するには `switch...case` ブロックを使うべきです。 + +`record` 引数は実際のプレスに関する情報を含みます: + +```c +keyrecord_t record { + keyevent_t event { + keypos_t key { + uint8_t col + uint8_t row + } + bool pressed + uint16_t time + } +} +``` + +# LED 制御 + +QMK は HID 仕様で定義された5つの LED の読み取りメソッドを提供します: + +* Num Lock +* Caps Lock +* Scroll Lock +* Compose +* Kana + +ロック LED の状態を取得するには2つの方法があります: + +* `bool led_update_kb(led_t led_state)` あるいは `_user(led_t led_state)` を実装する、または +* `led_t host_keyboard_led_state()` を呼び出す + +!> `host_keyboard_led_state()` は `led_update_user()` が呼ばれる前に新しい値を既に反映している場合があります。 + +LED の状態を `uint8_t` として提供する2つの非推奨の関数があります: + +* `uint8_t led_set_kb(uint8_t usb_led)` と `_user(uint8_t usb_led)` +* `uint8_t host_keyboard_leds()` + +## `led_update_user()` + +この関数はこれら5つの LED のいずれかの状態が変化すると呼ばれます。LED の状態を構造体のパラメータとして受け取ります。 + +慣例により、`led_update_kb()` にそのコードを実行するようフックさせるために `led_update_user()` から `true` を返し、`led_update_kb()` でコードを実行したくない場合は `false` を返します。 + +以下はいくつかの例です: + +- レイヤー表示のような何かのために LED を使うために LED を上書きする + - `_kb()` 関数を実行したくないので、`false` を返します。これはレイヤーの挙動を上書きするためです。 +- LED がオンあるいはオフになった時に音楽を再生する。 + - `_kb` 関数を実行したいので、`true` を返します。これはデフォルトの LED の挙動に追加されます。 + +?> `led_set_*` 関数は `bool` の代わりに `void` を返すため、キーボードの LED 制御を上書きすることができません。従って、代わりに `led_update_*` を使うことをお勧めします。 + +### `led_update_kb()` の実装例 + +```c +bool led_update_kb(led_t led_state) { + bool res = led_update_user(led_state); + if(res) { + // writePin は 1 でピンを high に、0 で low に設定します。 + // この例では、ピンは反転していて、 + // low/0 は LED がオンになり、high/1 は LED がオフになります。 + // この挙動は、LED がピンと VCC の間にあるか、ピンと GND の間にあるかどうかに依存します。 + writePin(B0, !led_state.num_lock); + writePin(B1, !led_state.caps_lock); + writePin(B2, !led_state.scroll_lock); + writePin(B3, !led_state.compose); + writePin(B4, !led_state.kana); + } + return res; +} +``` + +### `led_update_user()` の実装例 + +この不完全な例は Caps Lock がオンまたはオフになった場合に音を再生します。また LED の状態を保持する必要があるため、`true` を返します。 + +```c +#ifdef AUDIO_ENABLE + float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); + float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); +#endif + +bool led_update_user(led_t led_state) { + #ifdef AUDIO_ENABLE + static uint8_t caps_state = 0; + if (caps_state != led_state.caps_lock) { + led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); + caps_state = led_state.caps_lock; + } + #endif + return true; +} +``` + +### `led_update_*` 関数のドキュメント + +* キーボード/リビジョン: `bool led_update_kb(led_t led_state)` +* キーマップ: `bool led_update_user(led_t led_state)` + +## `host_keyboard_led_state()` + +最後に受信した LED の状態を `led_t` として取得するためにこの関数を呼びます。これは、`led_update_*` の外部から、例えば [`matrix_scan_user()`](#matrix-scanning-code) の中で LED の状態を読み取るのに便利です。 + +## 物理的な LED の状態の設定 + +一部のキーボードの実装は、物理的な LED の状態を設定するための便利なメソッドを提供しています。 + +### Ergodox キーボード + +Ergodox の実装は、個々の LED をオンあるいはオフにするために `ergodox_right_led_1`/`2`/`3_on`/`off()` と、インデックスによってそれらをオンあるいはオフにするために `ergodox_right_led_on`/`off(uint8_t led)` を提供します。 + +さらに、LED の明度を指定することができます。全ての LED に同じ明度を指定するなら `ergodox_led_all_set(uint8_t n)` を使い、個別の LED の明度を指定するなら `ergodox_right_led_1`/`2`/`3_set(uint8_t n)` を使い、LED のインデックスを指定して明度を指定するには `ergodox_right_led_set(uint8_t led, uint8_t n)` を使います。 + +Ergodox キーボードは、最低の明度として `LED_BRIGHTNESS_LO` を、最高の輝度(これはデフォルトです)として `LED_BRIGHTNESS_HI` も定義しています。 + +# キーボードの初期化コード + +キーボードの初期化プロセスには幾つかのステップがあります。何をしたいかによって、どの関数を使うべきかに影響します。 + +3つの主な初期化関数があり、呼び出される順番にリストされています。 + +* `keyboard_pre_init_*` - ほとんどのものが開始される前に起こります。非常に早くに実行したいハードウェアのセットアップに適しています。 +* `matrix_init_*` - ファームウェアのスタートアッププロセスの途中で起こります。ハードウェアは初期化されますが、機能はまだ初期化されていない場合があります。 +* `keyboard_post_init_*` - ファームウェアのスタートアッププロセスの最後に起こります。これはほとんどの場合、 "カスタマイズ"コードを配置する場所です。 + +!> ほとんどの人にとって、`keyboard_post_init_user` が呼び出したいものです。例えば、ここで RGB アンダーグローのセットアップを行います。 + +## キーボードの事前初期化コード + +これは USB さえ起動する前の、起動中の非常に早い段階で実行されます。 + +この直後にマトリックスが初期化されます。 + +これは主にハードウェア向きの初期化のためであるため、ほとんどのユーザは使うべきではありません。 + +ただし、初期化が必要なハードウェアがある場合には、これが最適な場所です (LED ピンの初期化など)。 + +### `keyboard_pre_init_user()` の実装例 + +この例は、キーボードレベルで、LED ピンとして B0、B1、B2、B3 および B4 をセットアップします。 + +```c +void keyboard_pre_init_user(void) { + // キーボードの事前初期コードを呼び出します。 + + // LED ピンを出力として設定します + setPinOutput(B0); + setPinOutput(B1); + setPinOutput(B2); + setPinOutput(B3); + setPinOutput(B4); +} +``` + +### `keyboard_pre_init_*` 関数のドキュメント :id=keyboard_pre_init_-function-documentation + +* キーボード/リビジョン: `void keyboard_pre_init_kb(void)` +* キーマップ: `void keyboard_pre_init_user(void)` + +## マトリックスの初期化コード + +これは、マトリックスが初期化され、ハードウェアの一部がセットアップされた後で、ただし機能の多くが初期化される前に、呼び出されます。 + +他の場所で必要になるかもしれないものをセットアップするのに役立ちますが、ハードウェアに関連するものではなく、開始場所に依存するものでもありません。 + + +### `matrix_init_*` 関数のドキュメント + +* キーボード/リビジョン: `void matrix_init_kb(void)` +* キーマップ: `void matrix_init_user(void)` + + +## キーボードの事後初期化コード + +キーボードの初期化プロセスの極めて最後のタスクとして実行されます。この時点で初期化される必要があるような、特定の機能を変更したい場合に便利です。 + + +### `keyboard_post_init_user()` の実装例 + +この例は、他の全てのものが初期化された後で実行され、rgb アンダーグローの設定をセットアップします。 + +```c +void keyboard_post_init_user(void) { + // post init コードを呼びます + rgblight_enable_noeeprom(); // 設定を保存せずに Rgb を有効にします + rgblight_sethsv_noeeprom(180, 255, 255); // 保存せずに色を青緑/シアンに設定します + rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // 保存せずにモードを高速なブリージングに設定します +} +``` + +### `keyboard_post_init_*` 関数のドキュメント + +* キーボード/リビジョン: `void keyboard_post_init_kb(void)` +* キーマップ: `void keyboard_post_init_user(void)` + +# マトリックススキャンコード :id=matrix-scanning-code + +可能であれば常に `process_record_*()` を使ってキーボードをカスタマイズし、その方法でイベントをフックし、コードがキーボードのパフォーマンスに悪影響を与えないようにします。ただし、まれにマトリックススキャンにフックする必要があります。これらの関数は1秒あたり少なくとも10回は呼び出されるため、これらの関数のコードのパフォーマンスに非常に注意してください。 + +### `matrix_scan_*` の実装例 + +この例は意図的に省略されています。このようなパフォーマンスに敏感な領域にフックする前に、例を使わずにこれを書くために、QMK 内部について十分理解する必要があります。助けが必要であれば、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new) か [Discord で会話](https://discord.gg/Uq7gcHh)してください。 + +### `matrix_scan_*` 関数のドキュメント + +* キーボード/リビジョン: `void matrix_scan_kb(void)` +* キーマップ: `void matrix_scan_user(void)` + +この関数はマトリックススキャンのたびに呼び出されます。これは基本的に MCU が処理できる頻度です。大量に実行されるため、ここに何を置くかについては注意してください。 + +カスタムマトリックススキャンコードが必要な場合は、この関数を使う必要があります。また、カスタムステータス出力 (LED あるいはディスプレイなど)や、ユーザが入力していない場合でも定期的にトリガーするその他の機能のために使うことができます。 + + +# キーボードアイドリング/ウェイクコード + +キーボードがサポートしている場合、多くの機能を停止することで"アイドル"にすることができます。これの良い例は、RGB ライトあるいはバックライトです。これにより、電力消費を節約できるか、キーボードの動作が改善されるかもしれません。 + +これは2つの関数によって制御されます: `suspend_power_down_*` および `suspend_wakeup_init_*`。これらはシステムキーボードがアイドルになった時と、起動した時のそれぞれで呼ばれます。 + + +### suspend_power_down_user() と suspend_wakeup_init_user() の実装例 + + +```c +void suspend_power_down_user(void) { + rgb_matrix_set_suspend_state(true); +} + +void suspend_wakeup_init_user(void) { + rgb_matrix_set_suspend_state(false); +} +``` + +### キーボードサスペンド/ウェイク関数のドキュメント + +* キーボード/リビジョン : `void suspend_power_down_kb(void)` および `void suspend_wakeup_init_user(void)` +* キーマップ: `void suspend_power_down_kb(void)` および `void suspend_wakeup_init_user(void)` + +# レイヤー切り替えコード :id=layer-change-code + +これはレイヤーが切り替えられるたびにコードを実行します。レイヤー表示あるいはカスタムレイヤー処理に役立ちます。 + +### `layer_state_set_*` の実装例 + +この例は、レイヤーに基づいて [RGB アンダーグロー](ja/feature_rgblight.md)を設定する方法を示していて、Planck を例として使っています。 + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _RAISE: + rgblight_setrgb (0x00, 0x00, 0xFF); + break; + case _LOWER: + rgblight_setrgb (0xFF, 0x00, 0x00); + break; + case _PLOVER: + rgblight_setrgb (0x00, 0xFF, 0x00); + break; + case _ADJUST: + rgblight_setrgb (0x7A, 0x00, 0xFF); + break; + default: // 他の全てのレイヤーあるいはデフォルトのレイヤー + rgblight_setrgb (0x00, 0xFF, 0xFF); + break; + } + return state; +} +``` + +特定のレイヤーの状態を確認するには、 `IS_LAYER_ON_STATE(state, layer)` と `IS_LAYER_OFF_STATE(state, layer)` マクロを使います。 + +`layer_state_set_*` 関数の外では、グローバルなレイヤー状態を確認するために `IS_LAYER_ON(layer)` と `IS_LAYER_OFF(layer)` マクロを使えます。 + +### `layer_state_set_*` 関数のドキュメント + +* キーボード/リビジョン: `layer_state_t layer_state_set_kb(layer_state_t state)` +* キーマップ: `layer_state_t layer_state_set_user(layer_state_t state)` + + +[キーマップの概要](ja/keymap.md#keymap-layer-status)で説明されるように、`state` はアクティブなレイヤーのビットマスクです。 + + +# 永続的な設定 (EEPROM) + +これによりキーボードのための永続的な設定を設定することができます。これらの設定はコントローラの EEPROM に保存され、電源が落ちた後であっても保持されます。設定は `eeconfig_read_kb` および `eeconfig_read_user` を使って読み取ることができ、`eeconfig_update_kb` および `eeconfig_update_user` を使って書きこむことができます。これは切り替え可能な機能 (rgb レイヤーの表示の切り替えなど)に役立ちます。さらに、`eeconfig_init_kb` および `eeconfig_init_user` を使って EEPROM のデフォルト値を設定できます。 + +ここでの複雑な部分は、EEPROM を介してデータを保存およびアクセスできる方法がたくさんあり、これを行うための"正しい"方法が無いということです。ただし、各関数には DWORD (4 バイト)しかありません。 + +EEPROM の書き込み回数には制限があることに注意してください。これは非常に高い値ですが、EEPROM に書き込むのはこれだけではなく、もし頻繁に書き込むと、MCU の寿命を大幅に短くする可能性があります。 + +* この例を理解していない場合は、この機能はかなり複雑なため、この機能を使うことを避けても構いません。 + +### 実装例 + +これは、設定を追加し、読み書きする例です。この例では、ユーザキーマップを使っています。これは複雑な機能で、多くのことが行われています。実際、動作のために上記の多くの関数を使います! + + +keymap.c ファイルの中で、先頭にこれを追加します: +```c +typedef union { + uint32_t raw; + struct { + bool rgb_layer_change :1; + }; +} user_config_t; + +user_config_t user_config; +``` + +これは、設定をメモリ内に保存し、EEPROM に書き込むことができる32ビット構造体をセットアップします。これを使うと、この構造体に変数が定義されるため、変数を定義する必要が無くなります。`bool` (boolean) の値は1ビットを使い、`uint8_t` は8ビットを使い、`uint16_t` は16ビットを使うことに注意してください。組み合わせて使うことができますが、順番の変更は読み書きされる値が変更されるため、問題が発生するかもしれません。 + +`layer_state_set_*` 関数のために `rgb_layer_change` を使い、全てを設定するために `keyboard_post_init_user` および `process_record_user` を使います。 + +ここで、上の `keyboard_post_init_user` コードを使って、作成したばかりの構造体を設定するために `eeconfig_read_user()` を追加します。そして、この構造体をすぐに使ってキーマップの機能を制御することができます。それは以下のようになります: +```c +void keyboard_post_init_user(void) { + // キーマップレベルのマトリックスの初期化処理を呼びます + + // EEPROM からユーザ設定を読み込みます + user_config.raw = eeconfig_read_user(); + + // 有効な場合はデフォルトレイヤーを設定します + if (user_config.rgb_layer_change) { + rgblight_enable_noeeprom(); + rgblight_sethsv_noeeprom_cyan(); + rgblight_mode_noeeprom(1); + } +} +``` +上記の関数は読み取ったばかりの EEPROM 設定を使い、デフォルトのレイヤーの RGB 色を設定します。その「生の」値は、上で作成した「共用体」に基づいて使用可能な構造に変換されます。 + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _RAISE: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } + break; + case _LOWER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } + break; + case _PLOVER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } + break; + case _ADJUST: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } + break; + default: // 他の全てのレイヤーあるいはデフォルトのレイヤー + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } + break; + } + return state; +} +``` +これにより、値が有効になっていた場合のみ、RGB アンダーグローが変更されます。この値を設定するために、`RGB_LYR` と呼ばれる `process_record_user` 用の新しいキーコードを作成します。さらに、通常の RGB コードを使う場合、上記の例を使ってオフになることを確認します。以下のようになります: +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // 押された時に何かをします + } else { + // 放された時に何かをします + } + return false; // このキーの以降の処理をスキップします + case KC_ENTER: + // enter が押された時に音を再生します + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // QMK に enter のプレスまたはリリースイベントを送信させます + case RGB_LYR: // これにより、アンダーグローをレイヤー表示として、あるいは通常通りに使うことができます。 + if (record->event.pressed) { + user_config.rgb_layer_change ^= 1; // 状態を切り替えます + eeconfig_update_user(user_config.raw); // 新しい状態を EEPROM に書き込みます + if (user_config.rgb_layer_change) { // レイヤーの状態表示が有効な場合 + layer_state_set(layer_state); // すぐにレイヤーの色を更新します + } + } + return false; + case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // 任意の RGB コード に対して(quantum_keycodes.h を見てください。400行目参照) + if (record->event.pressed) { // これはレイヤー表示を無効にします。これを変更する場合は、無効にしたいだろうため。 + if (user_config.rgb_layer_change) { // 有効な場合のみ + user_config.rgb_layer_change = false; // 無効にします + eeconfig_update_user(user_config.raw); // 設定を EEPROM に書き込みます + } + } + return true; break; + default: + return true; // 他の全てのキーコードを通常通りに処理します + } +} +``` +最後に、`eeconfig_init_user` 関数を追加して、EEPROM がリセットされた時にデフォルト値、さらにはカスタムアクションを指定できるようにします。EEPROM を強制的にリセットするには、`EEP_RST` キーコードあるいは[ブートマジック](ja/feature_bootmagic.md)機能を使います。例えば、デフォルトで rgb レイヤー表示を設定し、デフォルト値を保存したい場合。 + +```c +void eeconfig_init_user(void) { // EEPROM がリセットされます! + user_config.raw = 0; + user_config.rgb_layer_change = true; // デフォルトでこれを有効にします + eeconfig_update_user(user_config.raw); // デフォルト値を EEPROM に書き込みます + + // これらの値も EEPROM に書き込むためには、noeeprom 以外のバージョンを使います + rgblight_enable(); // デフォルトで RGB を有効にします + rgblight_sethsv_cyan(); // デフォルトでシアンに設定します + rgblight_mode(1); // デフォルトでソリッドに設定します +} +``` + +これで完了です。RGB レイヤー表示は必要な場合にのみ機能します。キーボードを取り外した後でも保存されます。RGB コードのいずれかを使うと、レイヤー表示が無効になり、設定したモードと色がそのままになります。 + +### 'EECONFIG' 関数のドキュメント + +* キーボード/リビジョン: `void eeconfig_init_kb(void)`、`uint32_t eeconfig_read_kb(void)` および `void eeconfig_update_kb(uint32_t val)` +* キーマップ: `void eeconfig_init_user(void)`、`uint32_t eeconfig_read_user(void)` および `void eeconfig_update_user(uint32_t val)` + +`val` は EEPROM に書き込みたいデータの値です。`eeconfig_read_*` 関数は EEPROM から32ビット(DWORD) 値を返します。 diff --git a/ja/documentation_best_practices.md b/ja/documentation_best_practices.md new file mode 100644 index 00000000000..c866d395993 --- /dev/null +++ b/ja/documentation_best_practices.md @@ -0,0 +1,69 @@ +# ドキュメントベストプラクティス + + + +このページは QMK のためのドキュメントを作成する時のベストプラクティスを文章化するためのものです。これらのガイドラインに従うことで、一貫したトーンとスタイルを維持することでき、他の人が QMK をより理解しやすくすることができます。 + +# ページの開始 + +ドキュメントページは通常 H1 ヘッダで始まり、最初の段落を使ってこのページの内容を説明します。この見出しと段落は目次の次にあるため、見出しは短くして空白の無い長い文字列を避けるように気を付けてください。 + +例: + +``` +# My Page Title + +This page covers my super cool feature. You can use this feature to make coffee, squeeze fresh oj, and have an egg mcmuffin and hashbrowns delivered from your local macca's by drone. +``` + +# 見出し + +通常、ページには複数の "H1" 見出しが有るべきです。H1 と H2 見出しのみが目次に含まれるので、適切に計画してください。目次が広くなりすぎないように、H1 と H2 の見出しでは幅を広げないようにしてください。 + +# スタイル付きのヒントブロック + +注意を引くためにテキストの周りにスタイル付きのヒントブロックを描くことができます。 + +### 重要なもの + +``` +!> This is important +``` + +以下のように表示されます: + +!> This is important + +### 一般的なヒント + +``` +?> This is a helpful tip. +``` + +以下のように表示されます: + +?> This is a helpful tip. + + +# 機能を文章化する + +QMK のために新しい機能を作成した場合、そのドキュメントページを作成してください。長い必要は無く、機能を説明する幾つかの文と、関連するキーコードを列挙した表で十分です。以下は基本的なテンプレートです: + +```markdown +# My Cool Feature + +This page describes my cool feature. You can use my cool feature to make coffee and order cream and sugar to be delivered via drone. + +## My Cool Feature Keycodes + +|Long Name|Short Name|Description| +|---------|----------|-----------| +|KC_COFFEE||Make Coffee| +|KC_CREAM||Order Cream| +|KC_SUGAR||Order Sugar| +``` + +ドキュメントを `docs/feature_.md` に配置し、そのファイルを `docs/_summary.md` の適切な場所に追加します。キーコードを追加した場合は、機能ページに戻るリンクとともに `docs/keycodes.md` に追加するようにしてください。 diff --git a/ja/documentation_templates.md b/ja/documentation_templates.md new file mode 100644 index 00000000000..a767c671a8b --- /dev/null +++ b/ja/documentation_templates.md @@ -0,0 +1,45 @@ +# ドキュメントテンプレート + + + +このページでは、新しいキーマップやキーボードを QMK に提出する際に使うべきテンプレートをまとめています。 + +## キーマップ `readme.md` テンプレート :id=keyboard-readmemd-template + +ほとんどのキーマップには、レイアウトを表す画像があります。画像を作成するには、[Keyboard Layout Editor](http://keyboard-layout-editor.com) を使うことができます。画像は [Imgur](http://imgur.com) や別のホスティングサービスにアップロードし、プルリクエストに画像を含めないでください。 + +画像の下には、キーマップを理解してもらうための簡単な説明文を書いてください。 + +``` +![Clueboard Layout Image](http://i.imgur.com/7Capi8W.png) + +# Default Clueboard Layout + +This is the default layout that comes flashed on every Clueboard. For the most +part it's a straightforward and easy to follow layout. The only unusual key is +the key in the upper left, which sends Escape normally, but Grave when any of +the Ctrl, Alt, or GUI modifiers are held down. +``` + +## キーボード `readme.md` テンプレート + +``` +# Planck + +![Planck](http://i.imgur.com/q2M3uEU.jpg) + +A compact 40% (12x4) ortholinear keyboard kit made and sold by OLKB and Massdrop. [More info on qmk.fm](http://qmk.fm/planck/) + +* Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert) +* Hardware Supported: Planck PCB rev1, rev2, rev3, rev4, Teensy 2.0 +* Hardware Availability: [OLKB.com](https://olkb.com), [Massdrop](https://www.massdrop.com/buy/planck-mechanical-keyboard?mode=guest_open) + +Make example for this keyboard (after setting up your build environment): + + make planck/rev4:default + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). +``` diff --git a/ja/driver_installation_zadig.md b/ja/driver_installation_zadig.md new file mode 100644 index 00000000000..bd794b40763 --- /dev/null +++ b/ja/driver_installation_zadig.md @@ -0,0 +1,53 @@ +# Zadig を使ったブートローダドライバのインストール + + + +QMK はホストにたいして通常の HID キーボードデバイスとして振る舞うため特別なドライバは必要ありません。しかし、Windows でのキーボードへの書き込みは、多くの場合、キーボードをリセットした時に現れるブートローダデバイスで*行います*。 + +2つの注目すべき例外があります: 通常 Pro Micro で見られる Caterina ブートローダや、PJRC Teensy に書き込まれている HalfKay ブートローダは、それぞれシリアルポートと汎用 HID デバイスとして振る舞うため、ドライバは必要ありません。 + +[Zadig](https://zadig.akeo.ie/) ユーティリティを使うことをお勧めします。MSYS2 あるいは WSL を使って開発環境をセットアップした場合、`qmk_install.sh` スクリプトはドライバをインストールするかどうかをたずねます。 + +## インストール + +`RESET` キーコード (別のレイヤにあるかもしれません)を押すか、通常はキーボードの下面にあるリセットスイッチを押して、キーボードをブートローダモードにします。どちらもキーボードに無い場合は、Escape または Space+`B` を押しながら接続してみてください (詳細は、[ブートマジック](ja/feature_bootmagic.md) ドキュメントを見てください)。一部のキーボードはブートマジックの代わりに[コマンド](ja/feature_command.md)を使います。この場合、キーボードが接続されている状態で「左Shift + 右Shift + `B`」あるいは「左Shift + 右Shift + Escape」を押すと、ブートローダモードに入ることができます。 +一部のキーボードはブートローダに入るために特定の操作をする必要があります。例えば、[ブートマジック Lite](ja/feature_bootmagic.md#bootmagic-lite) キー (デフォルト: Escape) は別のキー(例えば、左Control)かもしれません。また、コマンドを有効にするキーの組み合わせ (デフォルト: 左Shift + 右Shift) は何か他のキー(例えば 左Control + 右Control)を押し続ける必要がある場合があります。不明な場合は、キーボードの README ファイルを参照してください。 + +USBaspLoader を使ってデバイスをブートローダモードにするには、`BOOT` ボタンを押しながら `RESET` ボタンをタップしてください。 +あるいは `BOOT` を押し続けながら USB ケーブルを挿入します。 + +Zadig は自動的にブートローダデバイスを検知します。**Options → List All Devices** を確認する必要がある場合があります。 + +- Atmel AVR MCU を搭載したキーボードの場合、ブートローダは `ATm32U4DFU` に似た名前が付けられ、ベンダー ID は `03EB` です。 +- USBasp ブートローダは `USBasp` として表示され、VID/PID は`16C0:05DC` です。 +- QMK-DFU ブートローダを使って書き込まれた AVR キーボードは ` Bootloader` という名前が付けられ、VID は `03EB` です。 +- ほとんどの ARM キーボードでは、`STM32 BOOTLOADER` と呼ばれ、VID/PID は `0483:DF11` です。 + +!> Zadig が `HidUsb` ドライバを使用する1つ以上のデバイスを表示する場合、キーボードはおそらくブートローダモードではありません。矢印はオレンジ色になり、システムドライバの変更を確認するように求められます。この場合、続行**しないでください**! + +矢印が緑色で表示されたら、ドライバを選択し、**Install Driver** をクリックします。`libusb-win32` ドライバは通常 AVR で動作し、`WinUSB`は ARM で動作しますが、それでもキーボードに書き込みできない場合は、リストから異なるドライバをインストールしてみてください。USBAspLoader デバイスは `libusbK` ドライバを使わなければなりません。 + +![ブートローダドライバが正常にインストールされた Zadig](https://i.imgur.com/b8VgXzx.png) + +最後に、新しいドライバがロードされたことを確認するためにキーボードのプラグを抜いて再接続します。書き込みに QMK Toolbox を使う場合は、ドライバの変更を認識しない場合があるため、QMK Toolkit を終了して再起動します。 + +## 間違ったデバイスのインストールからの回復 + +キーボードが入力できなくなった場合は、ブートローダではなくキーボード自体のドライバを間違って入れ替えた可能性があります。これはキーボードがブートローダモードでない場合に起こりえます。これは Zadig で簡単に確認することができます - 健全なキーボードには、全てのインタフェースに `HidUsb` ドライバがインストールされています: + +![Zadig から見た健全なキーボード](https://i.imgur.com/Hx0E5kC.png) + +デバイスマネージャーを開き、キーボードと思われるデバイスを探します。 + +![デバイスマネージャーにおける、間違ったドライバがインストールされたキーボード](https://i.imgur.com/L3wvX8f.png) + +右クリックし、**デバイスのアンインストール** をクリックします。最初に **このデバイスのドライバーソフトウェアを削除します** にチェックが付いていることを確認してください。 + +!["ドライバの削除"にチェックボックスにチェックが付いた、デバイスのアンインストールダイアログ](https://i.imgur.com/aEs2RuA.png) + +**Action → Scan for hardware changes** をクリックします。この時点で、再び入力できるようになっているはずです。Zadig でキーボードデバイスが `HidUsb` ドライバを使っていることを再確認します。そうであれば完了です。キーボードは再び機能するはずです! + +?> Windows が新しいドライバを使えるようにするために、この時点でコンピュータを完全に再起動する必要があるかもしれません。 diff --git a/ja/faq_build.md b/ja/faq_build.md new file mode 100644 index 00000000000..3c93c078090 --- /dev/null +++ b/ja/faq_build.md @@ -0,0 +1,137 @@ +# よくあるビルドの質問 + + + +このページは QMK のビルドに関する質問を説明します。まだビルドをしていない場合は、[ビルド環境のセットアップ](ja/getting_started_build_tools.md) および [Make 手順](ja/getting_started_make_guide.md)ガイドを読むべきです。 + +## Linux でプログラムできません +デバイスを操作するには適切な権限が必要です。Linux ユーザの場合は、以下の `udev` ルールに関する指示を見てください。`udev` に問題がある場合は、回避策は `sudo` コマンドを使うことです。このコマンドに慣れていない場合は、`man sudo` コマンドでマニュアルを確認するか、[この web ページを見てください](https://linux.die.net/man/8/sudo)。 + +コントローラが ATMega32u4 の場合の `sudo` の使い方の例: + + $ sudo dfu-programmer atmega32u4 erase --force + $ sudo dfu-programmer atmega32u4 flash your.hex + $ sudo dfu-programmer atmega32u4 reset + +あるいは、単純に: + + $ sudo make ::flash + +`make` を `sudo` で実行することは一般的には良い考えでは***なく***、可能であれば前者の方法のいずれかを使うべきです。 + +### Linux の `udev` ルール + +Linux では、ブートローダデバイスと通信するには適切な権限が必要です。ファームウェアを書き込む時に `sudo` を使うか、`/etc/udev/rules.d/` にこのファイルを配置することで、通信することができます。 + +**/etc/udev/rules.d/50-qmk.rules:** +``` +# Atmel DFU +### ATmega16U2 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FEF", TAG+="uaccess", RUN{builtin}+="uaccess" +### ATmega32U2 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF0", TAG+="uaccess", RUN{builtin}+="uaccess" +### ATmega16U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF3", TAG+="uaccess", RUN{builtin}+="uaccess" +### ATmega32U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF4", TAG+="uaccess", RUN{builtin}+="uaccess" +### AT90USB64 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF9", TAG+="uaccess", RUN{builtin}+="uaccess" +### AT90USB128 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FFB", TAG+="uaccess", RUN{builtin}+="uaccess" + +# Input Club +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="B007", TAG+="uaccess", RUN{builtin}+="uaccess" + +# STM32duino +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1EAF", ATTRS{idProduct}=="0003", TAG+="uaccess", RUN{builtin}+="uaccess" +# STM32 DFU +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="DF11", TAG+="uaccess", RUN{builtin}+="uaccess" + +# BootloadHID +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16C0", ATTRS{idProduct}=="05DF", TAG+="uaccess", RUN{builtin}+="uaccess" + +# USBAspLoader +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16C0", ATTRS{idProduct}=="05DC", TAG+="uaccess", RUN{builtin}+="uaccess" + +# ModemManager should ignore the following devices +# Atmel SAM-BA (Massdrop) +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="6124", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" + +# Caterina (Pro Micro) +## Spark Fun Electronics +### Pro Micro 3V3/8MHz +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9203", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### Pro Micro 5V/16MHz +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9205", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### LilyPad 3V3/8MHz (and some Pro Micro clones) +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9207", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +## Pololu Electronics +### A-Star 32U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1FFB", ATTRS{idProduct}=="0101", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +## Arduino SA +### Leonardo +SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0036", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### Micro +SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0037", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +## Adafruit Industries LLC +### Feather 32U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000C", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### ItsyBitsy 32U4 3V3/8MHz +SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000D", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### ItsyBitsy 32U4 5V/16MHz +SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000E", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +## dog hunter AG +### Leonardo +SUBSYSTEMS=="usb", ATTRS{idVendor}=="2A03", ATTRS{idProduct}=="0036", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +### Micro +SUBSYSTEMS=="usb", ATTRS{idVendor}=="2A03", ATTRS{idProduct}=="0037", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" +``` + +追加が完了したら、以下を実行します: + +``` +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +**注意:** 古い(1.12以前の) ModemManager では、フィルタリングは厳密なモードではない場合にのみ動作し、以下のコマンドはその設定を更新することができます。 + +``` +printf '[Service]\nExecStart=\nExecStart=/usr/sbin/ModemManager --filter-policy=default' | sudo tee /etc/systemd/system/ModemManager.service.d/policy.conf +sudo systemctl daemon-reload +sudo systemctl restart ModemManager +``` + +### Linux のブートローダモードで Serial デバイスが検知されない +カーネルがデバイスを適切にサポートしていることを確認してください。デバイスが、Pro Micro (Atmega32u4) のように USB ACM を使う場合、`CONFIG_USB_ACM=y` を含めるようにしてください。他のデバイスは `USB_SERIAL` およびそのサブオプションを必要とするかもしれません。 + +## DFU ブートローダの不明なデバイス + +Windows 上でキーボードを書き込む時に発生する問題は、ブートローダ用に間違ったドライバがインストールされているか、全くインストールされていないかによるものがほとんどです。 + +QMK インストールスクリプト (MSYS2 あるいは WSL 内の `qmk_firmware` ディレクトリから `./util/qmk_install.sh`) を再実行するか、QMK Toolbox の再インストールでこの問題が解決するかもしれません。別のやり方として、手動で [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) パッケージをダウンロードして実行することができます。 + +それでもうまく行かない場合は、Zadig をダウンロードして実行する必要があります。詳細な情報は [Zadig を使ったブートローダドライバのインストール](ja/driver_installation_zadig.md)を見てください。 + +## USB VID と PID +`config.h` を編集することで任意の ID を使うことができます。おそらく未使用の ID を使っても、他の製品と衝突するとても低い可能性があることを除いて、実際には問題はありません。 + +QMK のほとんどのキーボードは、vendor ID として、`0xFEED` を使います。他のキーボードを調べて、ユニークな ID を選択してください。 + +またこれも見てください。 +https://github.com/tmk/tmk_keyboard/issues/150 + +ここで本当にユニークな VID:PID を買うことができます。個人的な使用にはこれは必要ないと思います。 +- http://www.obdev.at/products/vusb/license.html +- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 + +### キーボードに書き込んだが何も起こらない、あるいはキーの押下が登録されない - ARM (rev6 planck、clueboard 60、hs60v2 など) でも同じ (Feb 2019) +ARM ベースのチップ上での EEPROM の動作によって、保存された設定が無効になる場合があります。これはデフォルトレイヤに影響し、まだ調査中の特定の環境下でキーボードが使えなくなる*しれません*。EEPROM のリセットでこれが修正されます。 + +[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) を使って eeprom のリセットを強制することができます。このイメージを書き込んだ後で、通常のファームウェアを書き込むと、キーボードが_通常_ の動作順序に復元されます。 +[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) + +いずれかの形式でブートマジックが有効になっている場合は、これも実行できるはずです (実行方法の詳細については、[ブートマジックドキュメント](ja/feature_bootmagic.md)とキーボード情報を見てください)。 diff --git a/ja/faq_debug.md b/ja/faq_debug.md new file mode 100644 index 00000000000..39965b675b5 --- /dev/null +++ b/ja/faq_debug.md @@ -0,0 +1,140 @@ +# デバッグの FAQ + + + +このページは、キーボードのトラブルシューティングについての様々な一般的な質問を説明します。 + +# デバッグコンソール + +## `hid_listen` がデバイスを認識できない +デバイスのデバッグコンソールの準備ができていない場合、以下のように表示されます: + +``` +Waiting for device:......... +``` + +デバイスが接続されると、*hid_listen* がデバイスを見つけ、以下のメッセージが表示されます: + +``` +Waiting for new device:......................... +Listening: +``` + +この 'Listening:' のメッセージが表示されない場合は、[Makefile] を `CONSOLE_ENABLE=yes` に設定してビルドしてみてください + +Linux のような OS でデバイスにアクセスするには、権限が必要かもしれません。 +- `sudo hid_listen` を試してください + +## コンソールにメッセージが表示されない +以下を調べてください: +- *hid_listen* がデバイスを検出する。上記を見てください。 +- **Magic**+d を使ってデバッグを有効にする。[マジックコマンド](https://github.com/tmk/tmk_keyboard#magic-commands)を見てください。 +- `debug_enable=true` を設定します。[テストとデバッグ](ja/newbs_testing_debugging.md#debugging)を見てください +- デバッグ print の代わりに 'print' 関数を使ってみてください。**common/print.h** を見てください。 +- コンソール機能を持つ他のデバイスを切断します。[Issue #97](https://github.com/tmk/tmk_keyboard/issues/97) を見てください。 + +*** + +# 雑多なこと +## 安全性の考慮 + +あなたはおそらくキーボードを「文鎮化」したくないでしょう。文鎮化するとファームウェアを書き換えられないようになります。リスクがあまりに高い(そしてそうでないかもしれない)ものの一部のリストを示します。 + +- キーボードマップに RESET が含まれない場合、DFU モードに入るには、PCB のリセットボタンを押す必要があります。底部のネジを外す必要があります。 +- tmk_core / common にあるファイルを触るとキーボードが操作不能になるかもしれません。 +- .hex ファイルが大きすぎると問題を引き起こします; `make dfu` コマンドはブロックを削除し、 +サイズを検査し(おっと、間違った順序です!)、エラーを出力し、 +キーボードへの書き込みに失敗し、DFU モードのままになります。 + - この目的のためには、Planck の最大の .hex ファイルサイズは 7000h (10進数で28672)であることに注意してください。 + +``` +Linking: .build/planck_rev4_cbbrowne.elf [OK] +Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] + +Size after: + text data bss dec hex filename + 0 22396 0 22396 577c planck_rev4_cbbrowne.hex +``` + +- 上のファイルのサイズは 22396/577ch で、28672/7000h より小さいです +- 適切な替わりの .hex ファイルがある限り、それをロードして再試行することができます +- あなたがキーボードの Makefile で指定したかもしれない一部のオプションは、余分なメモリを消費します; BOOTMAGIC_ENABLE、MOUSEKEY_ENABLE、EXTRAKEY_ENABLE、CONSOLE_ENABLE、API_SYSEX_ENABLE に注意してください +- DFU ツールは(オプションの余計なフルーツサラダを投げ込まない限り)ブートローダに書き込むことを許可しないので、 +ここにはリスクはほとんどありません。 +- EEPROM の書き込みサイクルは、約100000です。ファームウェアを繰り返し継続的に書き換えるべきではありません。それは最終的に EEPROM を焼き焦がします。 + +## NKRO が動作しません +最初に、**Makefile** 内でビルドオプション `NKRO_ENABLE` を使ってファームウェアをコンパイルする必要があります。 + +**NKRO** がまだ動作しない場合は、`Magic` **N** コマンド(デフォルトでは `LShift+RShift+N`)を試してみてください。**NKRO** モードと **6KRO** モード間を一時的に切り替えるためにこのコマンドを使うことができます。**NKRO** が機能しない状況、特に BIOS の場合は **6KRO** モードに切り替える必要があります。 + +ファームウェアを `BOOTMAGIC_ENABLE` でビルドした場合、`ブートマジック` **N** コマンドで切り替える必要があります (デフォルトでは `Space+N`)。この設定は EEPROM に格納され、電源を入れ直しても保持されます。 + +https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch + + +## TrackPoint はリセット回路が必要です (PS/2 マウスサポート) +リセット回路が無いとハードウェアの不適切な初期化のために一貫性の無い結果になります。TPM754 の回路図を見てください。 + +- http://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 +- http://www.mikrocontroller.net/attachment/52583/tpm754.pdf + + +## 16 を超えるマトリックの列を読み込めない +列が 16 を超える場合、[matrix.h] の `read_cols()` 内の `1<<16` の代わりに `1UL<<16` を使ってください。 + +C では、AVR の場合 `1` は [16 bit] である [int] 型の1を意味し、15 を超えて左にシフトすることはできません。`1<<16` すると予期しないゼロが発生します。`1UL` として [unsigned long] 型を使う必要があります。 + +http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 + +## 特別なエクストラキーが動作しない (システム、オーディオコントロールキー) +QMK でそれらを使うには、`rules.mk` 内で `EXTRAKEY_ENABLE` を定義する必要があります。 + +``` +EXTRAKEY_ENABLE = yes # オーディオ制御とシステム制御 +``` + +## スリープから復帰しない + +Windows では、**デバイスマネージャ**の**電源の管理**タブ内の `このデバイスで、コンピュータのスタンバイ状態を解除できるようにする` 設定を調べてください。また BIOS 設定も調べてください。 + +スリープ中に任意のキーを押すとホストが起動するはずです。 + +## Arduino を使っていますか? + +**Arduino のピンの命名は実際のチップと異なることに注意してください。** 例えば、Arduino のピン `D0` は `PD0` ではありません。回路図を自身で確認してください。 + +- http://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf +- http://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf + +Arduino の Leonardo と micro には **ATMega32U4** が載っていて、TMK 用に使うことができますが、Arduino のブートローダが問題になることがあります。 + +## JTAG を有効にする + +デフォルトでは、キーボードが起動するとすぐに JTAG デバッグインタフェースが無効になります。JTAG 対応 MCU は `JTAGEN` ヒューズが設定された状態で出荷されており、キーボードがスイッチマトリックス、LED などに使用している可能性のある MCU の特定のピンを乗っ取ります。 + +JTAG を有効にしたままにしたい場合は、単に以下のものを `config.h` に追加します: + +```c +#define NO_JTAG_DISABLE +``` + +## USB 3 の互換性 +USB 3 ポートで問題がある人がいると聞きました。USB 2 ポートを試してください。 + + +## Mac の互換性 +### OS X 10.11 と Hub +https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 + + +## リジューム (スリープとウェークアップ)/電源サイクルの問題 +一部の人がキーボードが BIOS で動作しなくなった、またはリジューム(電源サイクル)の後で動作しなくなったと報告しました。 + +今のところ、この問題の根本は明確ではないですが、幾つかのビルドオプションが関係しているようです。Makefileで、`CONSOLE_ENABLE`、`NKRO_ENABLE`、`SLEEP_LED_ENABLE` あるいは他のオプションを無効にしてみてください。 + +https://github.com/tmk/tmk_keyboard/issues/266 +https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/ja/faq_general.md b/ja/faq_general.md new file mode 100644 index 00000000000..83d1a557bdd --- /dev/null +++ b/ja/faq_general.md @@ -0,0 +1,58 @@ +# よくある質問 + + + +## QMK とは何か? + +Quantum Mechanical Keyboard の略である [QMK](https://github.com/qmk) は、カスタムキーボードのためのツールをビルドしている人々のグループです。[TMK](https://github.com/tmk/tmk_keyboard) の大幅に修正されたフォークである [QMK ファームウェア](https://github.com/qmk/qmk_firmware)から始まりました。 + +## どこから始めればいいかわかりません! + +この場合は、[初心者ガイド](ja/newbs.md) から始めるべきです。ここには多くの素晴らしい情報があり、それらはあなたが始めるのに必要な全てをカバーするはずです。 + +問題がある場合は、[QMK Configurator](https://config.qmk.fm)にアクセスしてください。あなたが必要なものの大部分が処理されます。 + +## ビルドしたファームウェアを書き込むにはどうすればいいですか? + +まず、[コンパイル/書き込み FAQ ページ](ja/faq-build.md) に進みます。そこにはたくさんの情報があり、そこには一般的な問題に対する多くの解決策があります。 + +## ここで取り上げていない問題がある場合はどうしますか? + +OK、問題ありません。[GitHub で issue を開く](https://github.com/qmk/qmk_firmware/issues) をチェックして、誰かが同じこと(似ているかだけでなく実際に同じであることを確認してください)を経験しているかどうかを確認してください。 + +もし何も見つからない場合は、[新しい issue](https://github.com/qmk/qmk_firmware/issues/new) を開いてください! + +## バグを見つけたらどうしますか? + +[issue](https://github.com/qmk/qmk_firmware/issues/new) を開いてください。そしてもし修正方法を知っている場合は、GitHub で修正のプルリクエストを開いてください。 + +## しかし、`git` と `GitHub` は怖いです! + +心配しないでください。開発を容易にするために `git` と GitHub を使い始めるための、かなり良い [ガイドライン](ja/newbs_git_best_practices.md) があります。 + +さらに、追加の `git` と GitHub の関連リンクを [ここ](ja/newbs_learn_more_resources.md) に見つけることができます。 + +## サポートを追加したいキーボードがあります + +素晴らしい!プルリクエストを開いてください。私たちはコードをレビューし、マージします! + +### `QMK` でブランドしたい場合はどうればいいですか? + +素晴らしい!私たちはあなたを支援したいと思います! + +実際、私たちにはあなたのページとキーボードに QMK ブランドを追加するための [完全なページ](https://qmk.fm/powered/) があります。これは QMK を公式にサポートするために必要なほぼ全て(知識と画像)をカバーしています。 + +これについて質問がある場合は、issue を開くか、[Discord](https://discord.gg/Uq7gcHh) に進んでください。 + +## QMK と TMK の違いは何か? + +TMK は [Jun Wako](https://github.com/tmk) によって設計され実装されました。QMK は [Jack Humbert](https://github.com/jackhumbert) の Planck 用 TMK のフォークとして始まりました。しばらくして、Jack のフォークは TMK からかなり分岐し、2015年に Jack はフォークを QMK に名前を変えることにしました。 + +技術的な観点から、QMK は幾つかの新しい機能を追加した TMK に基づいています。最も注目すべきことは、QMK は利用可能なキーコードの数を増やし、`S()`、`LCTL()` および `MO()` などの高度な機能を実装するためにこれらを使っています。[キーコード](ja/keycodes.md)でこれらのキーコードの完全なリストを見ることができます。 + +プロジェクトとコミュニティの管理の観点から、TMK は公式にサポートされている全てのキーボードを自分で管理しており、コミュニティのサポートも少し受けています。他のキーボード用に別個のコミュニティが維持するフォークが存在するか、作成できます。デフォルトでは少数のキーマップのみが提供されるため、ユーザは一般的にお互いにキーマップを共有しません。QMK は集中管理されたリポジトリを介して、キーボードとキーマップの両方を共有することを奨励しており、品質基準に準拠する全てのプルリクエストを受け付けます。これらはほとんどコミュニティで管理されますが、必要な場合は QMK チームも支援します。 + +どちらのアプローチもメリットとデメリットがあり、理に適う場合は TMK と QMK の間でコードは自由にやり取りされます。 diff --git a/ja/faq_keymap.md b/ja/faq_keymap.md new file mode 100644 index 00000000000..311ebe0e429 --- /dev/null +++ b/ja/faq_keymap.md @@ -0,0 +1,160 @@ +# キーマップの FAQ + + + +このページは人々がキーマップについてしばしば持つ疑問について説明します。まだ読んだことが無い場合には、[キーマップの概要](ja/keymap.md)を最初に読むべきです。 + +## どのキーコードを使えますか? +あなたが利用可能なキーコードのインデックスについては、[キーコード](ja/keycodes.md)を見てください。より広範なドキュメントがある場合は、そこからリンクしてあります。 + +キーコードは実際には [common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/keycode.h) で定義されています。 + +## デフォルトのキーコードとは何か? + +世界中で使用されている ANSI、ISO および JIS の3つの標準キーボードがあります。北米では主に ANSI が使われ、ヨーロッパおよびアフリカでは主に ISO が使われ、日本では JIS が使われます。言及されていない地域では、ANSI あるいは ISO が使われています。これらのレイアウトに対応するキーコードは以下の通りです: + + +![キーボードのレイアウトイメージ](https://i.imgur.com/5wsh5wM.png) + +## 複雑なキーコードのカスタム名を作成する方法はありますか? + +時には、読みやすくするために、一部のキーコードにカスタム名を定義すると役に立ちます。人々は、しばしば `#define` を使ってカスタム名を定義します。例えば: + +```c +#define FN_CAPS LT(_FL, KC_CAPSLOCK) +#define ALT_TAB LALT(KC_TAB) +``` + +これにより、キーマップで `FN_CAPS` と `ALT_TAB` を使えるようになり、読みやすくなります。 + +## 一部のキーが入れ替わっているか、または動作しない + +QMK には2つの機能、ブートマジックとコマンドがあり、これによりその場でキーボードの動作を変更することができます。これには Ctrl/Caps の交換、Gui の無効化、Alt/Gui の交換、Backspace/Backslash の交換、全てのキーの無効化およびその他の動作の変更が含まれますが、これらに限定されません。 + +迅速な解決策として、キーボードを接続している時に `Space`+`Backspace` を押してみてください。これはキーボードに保存されている設定をリセットし、これらのキーを通常の操作に戻します。うまく行かない場合は、以下を見てください: + +* [ブートマジック](ja/feature_bootmagic.md) +* [コマンド](ja/feature_command.md) + +## メニューキーが動作しない + +ほとんどの最近のキーボードにある、`KC_RGUI` と `KC_RCTL` の間にあるキーは、実際には `KC_APP` と呼ばれます。これは、そのキーが発明された時に、関連する標準にすでに `MENU` という名前のキーが存在していたため、MS はそれを `APP` キーと呼ぶことを選択したためです。 + +## `KC_SYSREQ` が動作しません +`KC_SYSREQ` の代わりに、Print Screen(`KC_PSCREEN` あるいは `KC_PSCR`) のキーコードを使ってください。'Alt + Print Screen' のキーの組み合わせは、'システムリクエスト' と認識されます。 + +[issue #168](https://github.com/tmk/tmk_keyboard/issues/168) と以下を見てください +* http://en.wikipedia.org/wiki/Magic_SysRq_key +* http://en.wikipedia.org/wiki/System_request + +## 電源キーが動作しません + +やや紛らわしいことに、QMK には2つの "Power" キーコードがあります: キーボード/キーパッド HID usage page では `KC_POWER`、Consumer page では `KC_SYSTEM_POWER` (あるいは `KC_PWR`)。 + +前者は macOS でのみ認識されますが、後者 `KC_SLEP` および `KC_WAKE` は3つの主要なオペレーティングシステム全てでサポートされるため、これらを使うことをお勧めします。Windows ではこれらのキーはすぐに機能しますが、macOS ではそれらはダイアログが表示されるまで押し続ける必要があります。 + +## ワンショットモディファイア +私の個人的な 'the' の問題を解決します。'The' ではなく 'the' あるいは 'THe' を間違って入力することがありました。ワンショットシフトはこれを軽減します。 +https://github.com/tmk/tmk_keyboard/issues/67 + +## モディファイヤ/レイヤスタック +修飾キーあるいはレイヤは、レイヤの切り替えが適切に設定されていない場合、スタックするかもしれません。 +修飾キーおよびレイヤ切り替えの場合、リリースイベント時に修飾キーの登録を解除する、もしくは前のレイヤに戻るために、目的のレイヤの同じ位置に `KC_TRANS` を配置する必要があります。 + +* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching +* http://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 +* https://github.com/tmk/tmk_keyboard/issues/248 + + +## メカニカルロックスイッチのサポート + +この機能は [Alps](http://deskthority.net/wiki/Alps_SKCL_Lock) のような*メカニカルロックスイッチ*用です。以下を `config.h` に追加することで有効にすることができます: + +``` +#define LOCKING_SUPPORT_ENABLE +#define LOCKING_RESYNC_ENABLE +``` + +この機能を有効にした後で、キーマップでキーコード `KC_LCAP`、`KC_LNUM` および `KC_LSCR` を使います。 + +古いビンテージメカニカルキーボードにはロックスイッチが付いている場合がありますが、最新のものにはありません。***ほとんどの場合この機能は必要なく、単にキーコード `KC_CAPS`、`KC_NLCK` および `KC_SLCK`*** を使います。 + +## セディーユ 'Ç' のような ASCII 以外の特別文字の入力 + +[ユニコード](ja/feature_unicode.md) 機能を見てください。 + +## macOS での `Fn` キー + +ほとんどの Fn キーと異なり、Apple のキーボードの Fn キーには実際には独自のキーコードのようなものがあります。基本的な 6KRO HID レポートの6番目のキーコードの代わりになります -- つまり、Apple キーボードは実際には 5KRO のみです。 + +QMK にこのキーを送信させることは技術的に可能です。ただし、そうするには Fn キーの状態を追加するためにレポート形式の修正を必要とします。 +さらに悪いことに、キーボードの VID と PID が実際の Apple のキーボードのものと一致しない限り、認識されません。公式の QMK がこの機能をサポートすることで法的な問題が起きるため、サポートされることはないでしょう。 + +詳細については、[この issue](https://github.com/qmk/qmk_firmware/issues/2179) を見てください。 + +## Mac OSX でサポートされるキーは? +このソースコードから、どのキーコードが OSX でサポートされるかを知ることができます。 + +`usb_2_adb_keymap` 配列は、キーボード/キーパッドページの Page usages を ADB スキャンコード(OSX 内部キーコード)にマップします。 + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c + +`IOHIDConsumer::dispatchConsumerEvent` は Consumer page usages を処理します。 + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp + + +## Mac OSX での JIS キー +`無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` のような日本語 JIS キーボード固有のキーは OSX では認識されません。**Seil** を使ってこれらのキーを使うことができます。以下のオプションを試してください。 + +* PC キーボードで NFER キーを有効にする +* PC キーボードで XFER キーを有効にする +* PC キーボードで KATAKANA キーを有効にする + +https://pqrs.org/osx/karabiner/seil.html + + +## RN-42 Bluetooth が Karabiner で動作しない +Karabiner - Mac OSX 上のキーマッピングツール - は、デフォルトでは RN-42 モジュールからの入力を無視します。Karabiner をキーボードで動作させるにはこのオプションを有効にする必要があります。 +https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 + +この問題の詳細についてはこれらを見てください。 +https://github.com/tmk/tmk_keyboard/issues/213 +https://github.com/tekezo/Karabiner/issues/403 + + +## 単一のキーでの Esc と` + +[Grave Escape](ja/feature_grave_esc.md) 機能を見てください。 + +## Mac OSX での Eject +`KC_EJCT` キーコードは OSX で動作します。https://github.com/tmk/tmk_keyboard/issues/250 +Windows 10 はコードを無視し、Linux/Xorg は認識しますが、デフォルトではマッピングがありません。 + +実際の Apple キーボードにある Eject キーコードは実際には分かりません。HHKB は Mac モードでは Eject キー (`Fn+f`) に `F20` を使いますが、これはおそらく Apple の Eject キーコードと同じではありません。 + + +## `action_util.c` の `weak_mods` と `real_mods` は何か +___改善されるべきです___ + +real_mods は実際の物理的な修飾キーの状態を保持することを目的にしていますが、weak_mods は実際の修飾キーの状態に影響しない仮想あるいは一時的なモディファイアの状態を保持します。 + +物理的な左シフトキーを押しながら ACTION_MODS_KEY(LSHIFT, KC_A) を入力するとします + +weak_mods では、 +* (1) 左シフトキーを押し続ける: real_mods |= MOD_BIT(LSHIFT) +* (2) ACTION_MODS_KEY(LSHIFT, KC_A) を押す: weak_mods |= MOD_BIT(LSHIFT) +* (3) ACTION_MODS_KEY(LSHIFT, KC_A) を放す: weak_mods &= ~MOD_BIT(LSHIFT) +real_mods はモディファイアの状態を維持します。 + +weak mods 無しでは、 +* (1) 左シフトキーを押し続ける: real_mods |= MOD_BIT(LSHIFT) +* (2) ACTION_MODS_KEY(LSHIFT, KC_A) を押す: real_mods |= MOD_BIT(LSHIFT) +* (3) ACTION_MODS_KEY(LSHIFT, KC_A) を放す: real_mods &= ~MOD_BIT(LSHIFT) +ここで、real_mods は 'physical left shift' '物理的な左シフト' の状態を見失います。 + +キーボードレポートが送信される時、weak_mods は real_mods と論理和がとられます。 +https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/ja/feature_advanced_keycodes.md b/ja/feature_advanced_keycodes.md new file mode 100644 index 00000000000..502a67f80c4 --- /dev/null +++ b/ja/feature_advanced_keycodes.md @@ -0,0 +1,46 @@ +# 修飾キー :id=modifier-keys + + + +以下のようにキーコードとモディファイアを組み合わせることができます。押すと、モディファイアのキーダウンイベントが送信され、次に `kc` のキーダウンイベントが送信されます。放すと、`kc` のキーアップイベントが送信され、次にモディファイアのキーアップイベントが送信されます。 + +| キー | エイリアス | 説明 | +|----------|-------------------------------|----------------------------------------------------| +| `LCTL(kc)` | `C(kc)` | 左 Control を押しながら `kc` を押します。 | +| `LSFT(kc)` | `S(kc)` | 左 Shift を押しながら `kc` を押します。 | +| `LALT(kc)` | `A(kc)`, `LOPT(kc)` | 左 Alt を押しながら `kc`を押します。 | +| `LGUI(kc)` | `G(kc)`, `LCMD(kc)`, `LWIN(kc)` | 左 GUI を押しながら `kc` を押します。 | +| `RCTL(kc)` | | 右 Control を押しながら `kc` を押します。 | +| `RSFT(kc)` | | 右 Shift を押しながら `kc` を押します。 | +| `RALT(kc)` | `ROPT(kc)`, `ALGR(kc)` | 右 Alt を押しながら `kc` を押します。 | +| `RGUI(kc)` | `RCMD(kc)`, `LWIN(kc)` | 右 GUI を押しながら `kc` を押します。 | +| `SGUI(kc)` | `SCMD(kc)`, `SWIN(kc)` | 左 Shift と左 GUI を押しながら `kc` を押します。 | +| `LCA(kc)` | | 左 Control と左 Alt を押しながら `kc` を押します。 | +| `LCAG(kc)` | | 左 Control、左 Alt、左 GUI を押しながら `kc` を押します。 | +| `MEH(kc)` | | 左 Control、左 Shift、左 Alt を押しながら `kc` を押します。 | +| `HYPR(kc)` | | 左 Control、左 Shift、左 Alt、左 GUI を押しながら `kc` を押します。 | + +また、それらを繋げることができます。例えば、`LCTL(LALT(KC_DEL))` または `C(A(KC_DEL))` は1回のキー押下で Control+Alt+Delete を送信するキーを作成します。 + +# 過去の内容 :id=legacy-content + +このページには多くの機能が含まれていました。このページを構成していた多くのセクションをそれぞれのページに移動しました。これより下は全て単なるリダイレクトであるため、web上で古いリンクをたどっている人は探しているものを見つけることができます。 + +## レイヤー :id=switching-and-toggling-layers + +* [レイヤー](ja/feature_layers.md) + +## モッドタップ :id=mod-tap + +* [モッドタップ](ja/mod_tap.md) + +## ワンショットキー :id=one-shot-keys + +* [ワンショットキー](ja/one_shot_keys.md) + +## タップホールド設定オプション :id=tap-hold-configuration-options + +* [タップホールド設定オプション](ja/tap_hold.md) diff --git a/ja/feature_audio.md b/ja/feature_audio.md new file mode 100644 index 00000000000..2d13c3f7ccc --- /dev/null +++ b/ja/feature_audio.md @@ -0,0 +1,328 @@ +# オーディオ + + + +キーボードは音を出すことができます!Planck、Preonic あるいは特定の PWM 対応ピンにアクセスできる AVR キーボードがある場合は、単純なスピーカーを接続してビープ音を鳴らすことができます。これらのビープ音を使ってレイヤーの変化、モディファイア、特殊キーを示したり、あるいは単にイカした8ビットの曲を鳴らすことができます。 + +最大2つの同時オーディオ音声がサポートされ、1つはタイマー1によってもう一つはタイマー3によって駆動されます。以下のピンは config.h の中でオーディオ出力として定義することができます: + +Timer 1: +`#define B5_AUDIO` +`#define B6_AUDIO` +`#define B7_AUDIO` + +Timer 3: +`#define C4_AUDIO` +`#define C5_AUDIO` +`#define C6_AUDIO` + +`rules.mk` に `AUDIO_ENABLE = yes` を追加すると、他の設定無しで自動的に有効になる幾つかの異なるサウンドがあります: + +``` +STARTUP_SONG // キーボードの起動時に再生 (audio.c) +GOODBYE_SONG // RESET キーを押すと再生 (quantum.c) +AG_NORM_SONG // AG_NORM キーを押すと再生 (quantum.c) +AG_SWAP_SONG // AG_SWAP キーを押すと再生 (quantum.c) +CG_NORM_SONG // CG_NORM キーを押すと再生 (quantum.c) +CG_SWAP_SONG // CG_SWAP キーを押すと再生 (quantum.c) +MUSIC_ON_SONG // 音楽モードがアクティブになると再生 (process_music.c) +MUSIC_OFF_SONG // 音楽モードが非アクティブになると再生 (process_music.c) +CHROMATIC_SONG // 半音階音楽モードが選択された時に再生 (process_music.c) +GUITAR_SONG // ギター音楽モードが選択された時に再生 (process_music.c) +VIOLIN_SONG // バイオリン音楽モードが選択された時に再生 (process_music.c) +MAJOR_SONG // メジャー音楽モードが選択された時に再生 (process_music.c) +``` + +`config.h` の中で以下のような操作を行うことで、デフォルトの曲を上書きすることができます: + +```c +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(STARTUP_SOUND) +#endif +``` + +サウンドの完全なリストは、[quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) で見つかります - このリストに自由に追加してください!利用可能な音は [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h) で見つかります。 + +特定の時にカスタムサウンドを再生するために、以下のように曲を定義することができます(ファイルの上部付近に): + +```c +float my_song[][2] = SONG(QWERTY_SOUND); +``` + +以下のように曲を再生します: + +```c +PLAY_SONG(my_song); +``` + +または、以下のようにループで再生することができます: + +```c +PLAY_LOOP(my_song); +``` + +オーディオがキーボードに組み込まれていない時に問題が起きる事を避けるために、`#ifdef AUDIO_ENABLE` / `#endif` で全てのオーディオ機能をくるむことをお勧めします。 + +オーディオで利用可能なキーコードは以下の通りです: + +* `AU_ON` - オーディオ機能をオン +* `AU_OFF` - オーディオ機能をオフ +* `AU_TOG` - オーディオ機能を切り替え + +!> これらのキーコードは全てのオーディオ機能をオンおよびオフにします。オフにするとオーディオフィードバック、オーディオクリック、音楽モードなどが完全に無効になります。 + +## ARM オーディオボリューム + +ARM デバイスの場合、DAC サンプル値を調整できます。キーボードがあなたやあなたの同僚にとって騒々しい場合、`config.h` 内の `DAC_SAMPLE_MAX` を使って最大量を設定することができます: + +```c +#define DAC_SAMPLE_MAX 65535U +``` + +## 音楽モード + +音楽モードは列を半音階に、行をオクターブにマップします。これは格子配列キーボードで最適に動作しますが、他のものでも動作させることができます。`0xFF` 未満の全てのキーコードはブロックされるため、音の演奏中は入力できません - 特別なキー/mod があればそれらは引き続き動作します。これを回避するには、音楽モードを有効にする前(あるいは後)で、KC_NO を使って別のレイヤーにジャンプします。 + +メモリの問題により、録音は実験的です - 奇妙な動作が発生した場合は、キーボードの取り外しと再接続で問題が解決するでしょう。 + +利用可能なキーコード: + +* `MU_ON` - 音楽モードをオン +* `MU_OFF` - 音楽モードをオフ +* `MU_TOG` - 音楽モードの切り替え +* `MU_MOD` - 音楽モードの循環 + * `CHROMATIC_MODE` - 半音階。行はオクターブを変更します + * `GUITAR_MODE` - 半音階、ただし行は弦を変更します (+5 階) + * `VIOLIN_MODE` - 半音階。ただし行は弦を変換します (+7 階) + * `MAJOR_MODE` - メージャースケール + +音楽モードでは、以下のキーコードは動作が異なり、通過しません: + +* `LCTL` - 録音を開始 +* `LALT` - 録音を停止/演奏を停止 +* `LGUI` - 録音を再生 +* `KC_UP` - 再生をスピードアップ +* `KC_DOWN` - 再生をスローダウン + +ピッチ標準 (`PITCH_STANDARD_A`) はデフォルトで 440.0f です - これを変更するには、`config.h` に以下のようなものを追加します: + + #define PITCH_STANDARD_A 432.0f + +音楽モードも完全に無効にすることができます。コントローラの容量が足りなくて困っている場合に役に立ちます。無効にするには、これを `config.h` に追加します: + + #define NO_MUSIC_MODE + +### 音楽マスク + +デフォルトで、`MUSIC_MASK` は `keycode < 0xFF` に設定されます。これは、`0xFF` 未満のキーコードが音に変換され、何も出力しないことを意味します。`config.h` の中で以下のものを定義することで、これを変更することができます: + + #define MUSIC_MASK keycode != KC_NO + +これは全てのキーコードを捕捉します - これは、キーボードを再起動するまで、音楽モードで動けなくなることに注意してください! + +どのキーコードを引き続き処理するかを制御する、より高度な方法については、`.c` の中の `music_mask_kb(keycode)` および `keymap.c` の中の `music_mask_user(keycode)` を使うことができます: + + bool music_mask_user(uint16_t keycode) { + switch (keycode) { + case RAISE: + case LOWER: + return false; + default: + return true; + } + } + +false を返すものはマスクの一部では無く、常に処理されます。 + +### 音楽マップ + +デフォルトでは、音楽モードはキーのスケールを決定するために列と行を使います。キーボードレイアウトに一致する長方形のマトリックスを使うキーボードの場合、これで十分です。しかし、(Planck Rev6 あるいは多くの分割キーボードなどのように)より複雑なマトリックスを使うキーボードの場合、非常に歪んだ感じを受けることになります。 + +しかしながら、音楽マップオプションにより、音楽モードのためにスケーリングを再マップすることができるため、レイアウトに一致し、より自然になります。 + +この機能を使うには、`#define MUSIC_MAP` を `config.h` ファイルに追加します。そして、`キーボードの名前.c` または `keymap.c` に `uint8_t music_map` を追加します。 + +```c +const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x12( + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +); +``` + +キーボードが使用する `LAYOUT` マクロも使用したいでしょう。これは正しいキーの位置にマップします。キーボードレイアウトの左下から開始し、右に移動してさらに上に移動します。完全なマトリックスができるまで、全てのエントリを入力します。 + +これを実装する方法の例として、[Planck Keyboard](https://github.com/qmk/qmk_firmware/blob/e9ace1487887c1f8b4a7e8e6d87c322988bec9ce/keyboards/planck/planck.c#L24-L29) を見ることができます。 + +## オーディオクリック + +これは、ボタンを押すたびにクリック音を追加し、キーボードからのクリック音をシミュレートします。キーを押すたびにわずかに音が異なるため、すばやく入力しても長い単一の音のようには聞こえません。 + +* `CK_TOGG` - ステータスを切り替えます (有効にされた場合、音を再生します) +* `CK_ON` - オーディオクリックをオンにします (音を再生します) +* `CK_OFF` - オーディオクリックをオフにします (音を再生しません) +* `CK_RST` - 周波数をデフォルトの状態に再設定します (デフォルトの周波数で音を再生します) +* `CK_UP` - クリック音の周波数を増やします (新しい周波数で音を再生します) +* `CK_DOWN` - クリック音の周波数を減らします (新しい周波数で音を再生します) + + +容量を節約するためにデフォルトではこの機能は無効です。有効にするには、`config.h` に以下を追加します: + + #define AUDIO_CLICKY + + +これらの値を定義することで、デフォルト、最小および最大周波数、ステッピングおよび組み込みのランダム性を設定することができます: + +| オプション | デフォルト値 | 説明 | +|--------|---------------|-------------| +| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | クリック音のデフォルト/開始音の周波数を設定します。 | +| `AUDIO_CLICKY_FREQ_MIN` | 65.0f | 最小周波数を設定します (60f 未満は少しバグがあります)。 | +| `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | 最大周波数を設定します。高すぎると同僚があなたを攻撃する可能性があります。 | +| `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f | UP/DOWN キーコードのステップを設定します。これは掛け算の係数です。デフォルトでは、音楽のマイナーの1/3ずつ、周波数を上げ/下げします。 | +| `AUDIO_CLICKY_FREQ_RANDOMNESS` | 0.05f | クリックのランダム性の係数を設定します。これを `0f` に設定すると各クリックが同一になり、`1.0f` に設定するとこの音は90年代のコンピュータ画面のスクロール/タイピングの効果があります。 | +| `AUDIO_CLICKY_DELAY_DURATION` | 1 | 1がテンポの 1/16、または64分音符である整数音符の長さ (実装の詳細については、`quantum/audio/musical_notes.h` を見てください)。メインのクリック効果は、この時間だけ遅れます。これらを6-12前後の値に調整すると、うるさいスイッチの補正に役立ちます。 | + + + + +## MIDI 機能 + +これはまだ WIP ですが、何が起きているかを見るために、`quantum/process_keycode/process_midi.c` を調べてください。Makefile から有効にします。 + + +## オーディオキーコード + +| キー | エイリアス | 説明 | +|----------------|---------|----------------------------------| +| `AU_ON` | | オーディオモードオン | +| `AU_OFF` | | オーディオモードオフ | +| `AU_TOG` | | オーディオモードを切り替えます | +| `CLICKY_TOGGLE` | `CK_TOGG` | オーディオクリックモードを切り替えます | +| `CLICKY_UP` | `CK_UP` | クリック音の周波数を増やします | +| `CLICKY_DOWN` | `CK_DOWN` | クリック音の周波数を減らします | +| `CLICKY_RESET` | `CK_RST` | 周波数をデフォルトに再設定します | +| `MU_ON` | | 音楽モードをオンにします | +| `MU_OFF` | | 音楽モードをオフにします | +| `MU_TOG` | | 音楽モードを切り替えます | +| `MU_MOD` | | 音楽モードを循環します | + + diff --git a/ja/feature_auto_shift.md b/ja/feature_auto_shift.md new file mode 100644 index 00000000000..cf67b339771 --- /dev/null +++ b/ja/feature_auto_shift.md @@ -0,0 +1,135 @@ +# 自動シフト: なぜシフトキーが必要ですか? + + + +キーをタップすると、その文字を取得します。キーをタップするが、*わずかに*長く押し続けると、シフト状態になります。ほら!シフトキーは必要ありません! + +## なぜ自動シフトなのですか? + +多くの人が腱鞘炎などの症状に苦しんでいます。一般的な原因は、指を繰り返し長い距離を伸ばすことです。私たちはキーボード上でシフトキーに手を伸ばすためにあまりにも頻繁に小指を伸ばします。自動シフトキーはそれを軽減しようとしています。 + +## どのように動作しますか? + +キーをタップする時に、キーを放す前にほんの短い間押したままにします。この押したままにする時間は全ての人にとって異なる長さです。自動シフトは、定数 `AUTO_SHIFT_TIMEOUT` を定義し、これは普段の押された状態の時間の2倍に通常は設定されます。タイマーは、キーを押す時に開始され、キーを放す時に止まります。押された時間が `AUTO_SHIFT_TIMEOUT` 以上の場合に、キーのシフトバージョンが発行されます。時間が `AUTO_SHIFT_TIMEOUT` 時間よりも短い場合は、通常の状態が発行されます。 + +## 自動シフトには制限がありますか? + +残念ながらあります。 + +1. キーリピートが動作しなくなります。例えば、20個の 'a' 文字が必要な場合、'a' キーを1、2秒押し続けるかもしれません。オペレーティングシステムに押されたキーの状態を発行する代わりに押された時間を計るので、自動シフトでは動作しません。 +2. シフトをするつもりがない時にシフトされた文字を取得し、シフトしたい時にそうではない他の文字を取得するでしょう。これは結局は練習になります。急いでいる時は、シフトされたバージョンのために十分長くキーを押したと思うかもしれませんが、そうではありませんでした。一方、キーをタップしていると思うかもしれませんが、実際には予想よりも少し長い間押していました。 + +## どうやって自動シフトを有効にしますか? + +キーマップフォルダの `rules.mk` に追加します: + + AUTO_SHIFT_ENABLE = yes + +`rules.mk` が存在しない場合、それを作成することができます。 + +そして自動シフトキーを有効にした新しいファームウェアをコンパイルしてインストールします!以上です! + +## モディファイア + +デフォルトで、1つ以上のモディファイアと一緒にキーが押されると自動シフトは無効になります。従って、本当に長い間 Ctrl+A を保持しても、Ctrl+Shift+A と同じではありません。 + +`config.h` に定義を追加することで、モディファイアの自動シフトを再度有効にすることができます + +```c +#define AUTO_SHIFT_MODIFIERS +``` + +この場合、`AUTO_SHIFT_TIMEOUT` を超えて押された Ctrl+A は Ctrl+Shift+A として送信されます + + +## 自動シフトの設定 + +必要に応じて、自動シフトの挙動を変更することができる幾つかの設定があります。キーマップフォルダにある `config.h` に様々な変数を設定することで行われます。`config.h` ファイルが存在しない場合、それを作成することができます。 + +例 + +```c +#pragma once + +#define AUTO_SHIFT_TIMEOUT 150 +#define NO_AUTO_SHIFT_SPECIAL +``` + +### AUTO_SHIFT_TIMEOUT (単位: ミリ秒) + +これは、シフトされた状態を取得するためにどれだけ長くキーを押し続けなければならないかを制御します。 +明らかにこれは人によって異なります。一般的な人にとって、135 から 150 の設定がうまく機能します。ただし、少なくとも 175 の値から開始する必要があります。これはデフォルト値です。その後、ここから下げていきます。間違って検出することなくシフトされた状態を取得するのに必要な、最も短い時間を得るという考え方です。 + +完璧に動作するまで、いろいろな値を試してみます。多くの人は、全てが所定の値で適切に動作するものの、時々、1つあるいは2つのキーがシフト状態を発行することが分かるでしょう。これは単に習慣と、幾つかのキーを他のキーよりも少し長く押し続けることによるものです。この値を見つけたら、問題のキーを通常よりも少し早くタップするとともに、その値を設定します。 + +?> 自動シフトには、この値を素早く取得するのに役立つ3つの特別なキーがあります。詳細は「自動シフトのセットアップ」を見てください! + +### NO_AUTO_SHIFT_SPECIAL (単純にこのように定義します) + +-\_, =+, [{, ]}, ;:, '", ,<, .> および /? を含む特殊キーを自動シフトしません + +### NO_AUTO_SHIFT_NUMERIC (単純にこのように定義します) + +0から9までの数字キーを自動シフトしません。 + +### NO_AUTO_SHIFT_ALPHA (単純にこのように定義します) + +AからZを含むアルファベット文字を自動シフトしません。 + +## 自動シフトセットアップの使用 + +これにより、`AUTO_SHIFT_TIMEOUT` で設定している時間を一時的に増減させたり報告するために、3つのキーを定義することができます。 + +### セットアップ + +3つのキーを一時的にキーマップにマップします: + +| キー名 | 説明 | +|----------|-----------------------------------------------------| +| KC_ASDN | 自動シフトタイムアウト変数を下げる | +| KC_ASUP | 自動シフトタイムアウト変数を上げる | +| KC_ASRP | 現在の自動シフトタイムアウト値を報告する | +| KC_ASON | 自動シフト機能をオンにする | +| KC_ASOFF | 自動シフト機能をオフにする | +| KC_ASTG | 自動シフト機能の状態を切り替える | + +新しいファームウェアをコンパイルしてアップロードします。 + +### 使い方 + +これらのテスト中は、完全に普段通り入力する必要があり、意図的にシフトされたキーを使わずに入力するように注意する必要があります。 + +1. アルファベットの複数の文を入力します。 +2. 大文字に注意してください。 +3. 大文字が存在しない場合は、自動シフトタイムアウト値を減らすために `KC_ASDN` にマップしたキーを押し、ステップ1に戻ります。 +4. 大文字が幾つかある場合は、押す時間を短くしてこれらのキーをタップする必要があるか、あるいはタイムアウトを増やす必要があるかを決定します。 +5. タイムアウトを増やすことに決めた場合は、`KC_ASUP` にマップしたキーを押し、ステップ1に戻ります。 +6. 結果に満足したら、`KC_ASRP` にマップしたキーを押します。キーボードは `AUTO_SHIFT_TIMEOUT` の値を自動的に入力します。 +7. 報告された値で `config.h` の `AUTO_SHIFT_TIMEOUT` を更新します。 +8. `config.h` に `AUTO_SHIFT_NO_SETUP` を追加します。 +9. `KC_ASDN`、`KC_ASUP` および `KC_ASRP` のキーバインディングを削除します。 +10. 新しいファームウェアをコンパイルしてアップロードします。 + +#### 実行例 + + hello world. my name is john doe. i am a computer programmer playing with + keyboards right now. + + [KC_ASDN を何度か押します] + + heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH + KEYboArDS RiGHT NOw. + + [KC_ASUP を数回押します] + + hello world. my name is john Doe. i am a computer programmer playing with + keyboarDs right now. + + [KC_ASRPを押します] + + 115 + +キーボードは現在の `AUTO_SHIFT_TIMEOUT` 値を表す `115` を入力しました。これで設定が完了しました!テスト中に現れる *D* キーを少し練習してください。それで完璧です。 diff --git a/ja/feature_backlight.md b/ja/feature_backlight.md new file mode 100644 index 00000000000..88afa6c5fe6 --- /dev/null +++ b/ja/feature_backlight.md @@ -0,0 +1,222 @@ +# バックライト :id=backlighting + + + +多くのキーボードは、キースイッチを貫通して配置されたり、キースイッチの下に配置された個々の LED によって、バックライトキーをサポートします。この機能は通常スイッチごとに単一の色しか使用できないため、[RGB アンダーグロー](ja/feature_rgblight.md)および [RGB マトリックス](ja/feature_rgb_matrix.md)機能のどちらとも異なりますが、キーボードに複数の異なる単一色の LED を取り付けることは当然可能です。 + +QMK は *パルス幅変調* (*Pulse Width Modulation*) すなわち PWM として知られている技術で、一定の比率で素早くオンおよびオフを切り替えることで、これらの LED の輝度を制御できます。PWM 信号のデューティサイクルを変えることで、調光の錯覚を起こすことができます。 + +MCU は、GPIO ピンにはそんなに電流を供給できません。MCU から直接バックライトに給電せずに、バックライトピンは LED への電力を切り替えるトランジスタあるいは MOSFET に接続されます。 + +ほとんどのキーボードではバックライトをサポートしている場合にデフォルトで有効になっていますが、もし機能しない場合は `rules.mk` が以下を含んでいることを確認してください: + +```makefile +BACKLIGHT_ENABLE = yes +``` + +## キーコード :id=keycodes + +有効にすると、以下のキーコードを使ってバックライトレベルを変更することができます。 + +| キー | 説明 | +| --------- | ------------------------------------ | +| `BL_TOGG` | バックライトをオンあるいはオフにする | +| `BL_STEP` | バックライトレベルを循環する | +| `BL_ON` | バックライトを最大輝度に設定する | +| `BL_OFF` | バックライトをオフにする | +| `BL_INC` | バックライトレベルを上げる | +| `BL_DEC` | バックライトレベルを下げる | +| `BL_BRTG` | バックライトの明滅動作を切り替える | + +## 関数群 :id=functions + +次の関数を使って、カスタムコードでバックライトを変更することができます: + +| 関数 | 説明 | +| ------------------------ | -------------------------------------------- | +| `backlight_toggle()` | バックライトをオンあるいはオフにする | +| `backlight_enable()` | バックライトをオンにする | +| `backlight_disable()` | バックライトをオフにする | +| `backlight_step()` | バックライトレベルを循環する | +| `backlight_increase()` | バックライトレベルを上げる | +| `backlight_decrease()` | バックライトレベルを下げる | +| `backlight_level(x)` | バックライトのレベルを特定のレベルに設定する | +| `get_backlight_level()` | 現在のバックライトレベルを返す | +| `is_backlight_enabled()` | バックライトが現在オンかどうかを返す | + +バックライトの明滅が有効の場合(以下を参照)、以下の関数も利用できます: + +| 関数 | 説明 | +|-----------------------|----------------------------------------------| +| `breathing_toggle()` | バックライトの明滅動作をオンまたはオフにする | +| `breathing_enable()` | バックライトの明滅動作をオンにする | +| `breathing_disable()` | バックライトの明滅動作をオフにする | + +## 設定 :id=configuration + +どのドライバを使うかを選択するには、以下を使って `rules.mk` を設定します: + +```makefile +BACKLIGHT_DRIVER = software +``` + +有効なドライバの値は `pwm`, `software`, `custom`, `no` です。各ドライバについてのヘルプは以下を見てください。 + +バックライトを設定するには、`config.h` の中で以下の `#define` をします: + +| 定義 | デフォルト | 説明 | +| --------------------- | ---------- | ------------------------------------------------------------------------------------------- | +| `BACKLIGHT_PIN` | *定義なし* | LED を制御するピン | +| `BACKLIGHT_LEVELS` | `3` | 輝度のレベルの数 (オフを除いて最大 31) | +| `BACKLIGHT_CAPS_LOCK` | *定義なし* | バックライトを使って Caps Lock のインジケータを有効にする (専用 LED の無いキーボードのため) | +| `BACKLIGHT_BREATHING` | *定義なし* | サポートされる場合は、バックライトの明滅動作を有効にする | +| `BREATHING_PERIOD` | `6` | 各バックライトの "明滅" の長さ(秒) | +| `BACKLIGHT_ON_STATE` | `1` | バックライトが "オン" の時のバックライトピンの状態 - high の場合は `1`、low の場合は `0` | + +独自のキーボードを設計しているわけではない限り、通常は `BACKLIGHT_PIN` または `BACKLIGHT_ON_STATE` を変更する必要はありません。 + +### バックライトオン状態 :id=backlight-on-state + +ほとんどのバックライトの回路は N チャンネルの MOSFET あるいは NPN トランジスタによって駆動されます。これは、トランジスタを *オン* にして LED を点灯させるには、ゲートまたはベースに接続されているバックライトピンを *high* に駆動する必要があることを意味します。 +ただし、P チャンネルの MOSFET あるいは PNP トランジスタが使われる場合があります。この場合、トランジスタがオンの時、ピンは代わりに *low* で駆動されます。 + +この機能は `BACKLIGHT_ON_STATE` を定義することでキーボードレベルで設定されます。 + +### AVR ドライバ :id=avr-driver + +`pwm` ドライバはデフォルトで設定されますが、`rules.mk` 内での同等の設定は以下の通りです: + +```makefile +BACKLIGHT_DRIVER = pwm +``` + +#### 注意事項 :id=avr-caveats + +AVR ボードでは、QMK はどのドライバを使うかを以下の表に従って自動的に決定します: + +| バックライトピン | AT90USB64/128 | ATmega16/32U4 | ATmega16/32U2 | ATmega32A | ATmega328/P | +| ---------------- | ------------- | ------------- | ------------- | --------- | ----------- | +| `B1` | | | | | Timer 1 | +| `B2` | | | | | Timer 1 | +| `B5` | Timer 1 | Timer 1 | | | | +| `B6` | Timer 1 | Timer 1 | | | | +| `B7` | Timer 1 | Timer 1 | Timer 1 | | | +| `C4` | Timer 3 | | | | | +| `C5` | Timer 3 | | Timer 1 | | | +| `C6` | Timer 3 | Timer 3 | Timer 1 | | | +| `D4` | | | | Timer 1 | | +| `D5` | | | | Timer 1 | | + +他の全てのピンはタイマー支援ソフトウェア PWM を使います。 + +| オーディオピン | オーディオタイマ | ソフトウェア PWM タイマ | +| -------------- | ---------------- | ----------------------- | +| `C4` | Timer 3 | Timer 1 | +| `C5` | Timer 3 | Timer 1 | +| `C6` | Timer 3 | Timer 1 | +| `B5` | Timer 1 | Timer 3 | +| `B6` | Timer 1 | Timer 3 | +| `B7` | Timer 1 | Timer 3 | + +両方のタイマーがオーディオのために使われている場合、バックライト PWM はハードウェアタイマを使うことができず、代わりにマトリックススキャンの間に引き起こされます。この場合、PWM の計算は十分なタイミングの精度で呼ばれない可能性があるため、バックライトの明滅はサポートされず、バックライトもちらつくかもしれません。 + +#### ハードウェア PWM 実装 :id=hardware-pwm-implementation + +バックライト用にサポートされているピンを使う場合、QMK は PWM 信号を出力するように設定されたハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。 +希望の輝度が計算され、`OCRxx` レジスタに格納されます。カウンタがこの値まで達すると、バックライトピンは low になり、カウンタがリセットされると再び high になります。 +このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。`0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。 + +明滅動作の効果はカウンタがリセットされる(秒間あたりおよそ244回)たびに呼び出される `TIMER1_OVF_vect` の割り込みハンドラを登録することで可能になります。 +このハンドラで、増分カウンタの値が事前に計算された輝度曲線にマップされます。明滅動作をオフにするには、割り込みを単純に禁止し、輝度を EEPROM に格納されているレベルに再設定します。 + +#### タイマー支援 PWM 実装 :id=timer-assisted-implementation + +`BACKLIGHT_PIN` がハードウェアバックライトピンに設定されていない場合、QMK はソフトウェア割り込みを引き起こすように設定されているハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。 +0 に再設定すると、CPU は LED をオンにする OVF (オーバーフロー)割り込みを発火し、デューティサイクルを開始します。 +希望の輝度が計算され、`OCRxx` レジスタに格納されます。カウンタがこの値に達すると、CPU は比較出力一致割り込みを発火し、LED をオフにします。 +このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。 `0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。 + +明滅の効果はハードウェア PWM 実装と同じです。 + +### ARM ドライバ :id=arm-configuration + +まだ初期段階ですが、ARM バックライトサポートは最終的に AVR と同等の機能を持つことを目指しています。`pwm` ドライバはデフォルトで設定されますが、`rules.mk` 内での同等の設定は以下の通りです: + +```makefile +BACKLIGHT_DRIVER = pwm +``` + +#### ChibiOS の設定 :id=arm-configuration + +以下の `#define` は ARM ベースのキーボードにのみ適用されます: + +| 定義 | デフォルト | 説明 | +| ----------------------- | ---------- | ----------------------- | +| `BACKLIGHT_PWM_DRIVER` | `PWMD4` | 使用する PWM ドライバ | +| `BACKLIGHT_PWM_CHANNEL` | `3` | 使用する PWM チャンネル | +| `BACKLIGHT_PAL_MODE` | `2` | 使用するピン代替関数 | + +これらの値を決定するには、特定の MCU の ST データシートを参照してください。独自のキーボードを設計しているわけではない場合、通常はこれらを変更する必要はありません。 + +#### 注意事項 :id=arm-caveats + +現在のところ、ハードウェア PWM のみがサポートされ、タイマー支援はなく、自動設定は提供されません。 + +### ソフトウェア PWM ドライバ :id=software-pwm-driver + +このモードでは、他のキーボードのタスクを実行中に PWM は「エミュレート」されます。追加のプラットフォーム設定なしで最大のハードウェア互換性を提供します。トレードオフは、キーボードが忙しい時にバックライトが揺れる可能性があることです。有効にするには、`rules.mk` に以下を追加します: + +```makefile +BACKLIGHT_DRIVER = software +``` + +#### 複数のバックライトピン :id=multiple-backlight-pins + +ほとんどのキーボードは、全てのバックライト LED を制御するたった1つのバックライトピンを持ちます (特にバックライトがハードウェア PWM ピンに接続されている場合)。 +ソフトウェア PWM では、複数のバックライトピンを定義することができます。これらのピンは PWM デューティサイクル時に同時にオンおよびオフになります。 + +この機能により、例えば Caps Lock LED (またはその他の制御可能な LED) の輝度を、バックライトの他の LED と同じレベルに設定することができます。Caps Lock LED は通常バックライトとは別のピンに配線されるため、Caps Lock の代わりに Control をマップしていて、Caps Lock がオンの時に Caps Lock LED ではなくバックライトの一部をアクティブにする必要がある場合に便利です。 + +複数のバックライトピンをアクティブにするには、`config.h` に `BACKLIGHT_PIN` の代わりに次のようなものを追加します: + +```c +#define BACKLIGHT_PINS { F5, B2 } +``` + +### カスタムドライバ :id=custom-driver + +上記ドライバのいずれもキーボードに適用されていない場合(例えば、バックライトを制御するのに別の IC を使用している場合)、QMK が提供しているこの簡単な API を使ってカスタムバックライトドライバを実装することができます。有効にするには、`rules.mk` に以下を追加します: + +```makefile +BACKLIGHT_DRIVER = custom +``` + +それから次のフックのいずれかを実装します: + +```c +void backlight_init_ports(void) { + // オプション - 起動時に実行されます + // 通常、ここでピンを設定します +} +void backlight_set(uint8_t level) { + // オプション - レベルの変更時に実行されます + // 通常、ここで新しい値に応答します +} + +void backlight_task(void) { + // オプション - 定期的に実行されます + // これはメインキーボードループで呼び出されることに注意してください + // そのため、ここで長時間実行されるアクションはパフォーマンスの問題を引き起こします +} +``` + +## 回路図の例 + +この一般的な例では、バックライト LED は全て N チャンネル MOSFET に向かって並列に接続されています。そのゲートピンは、リンギングを回避するため 470Ωの抵抗を介してマイクロコントローラの GPIO ピンの1つに接続されています。 +プルダウン抵抗もゲートピンとグランドの間に配置されており、MCU によって駆動されていない場合にプルダウン抵抗を定義された状態に保ちます。 +これらの抵抗値は重要ではありません。詳細については、[this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) を参照してください。 + +![バックライトの回路例](https://i.imgur.com/BmAvoUC.png) diff --git a/ja/feature_bluetooth.md b/ja/feature_bluetooth.md new file mode 100644 index 00000000000..3c71a18ec1f --- /dev/null +++ b/ja/feature_bluetooth.md @@ -0,0 +1,49 @@ +# Bluetooth + + + +## Bluetooth の既知のサポートハードウェア + +現在のところ Bluetooth のサポートは AVR ベースのチップに限られます。Bluetooth 2.1 については、QMK は RN-42 モジュールをサポートします。より最近の BLE プロトコルについては、現在のところ Adafruit Bluefruit SPI Friend のみが直接サポートされています。iOS デバイスに接続するには、BLE が必要です。iOS はマウス入力をサポートしないことに注意してください。 + +| ボード | Bluetooth プロトコル | 接続タイプ | rules.mk | Bluetooth チップ | +| ---------------------------------------------------------------- | -------------------- | ---------- | ------------------------- | ---------------- | +| Roving Networks RN-42 (Sparkfun Bluesmirf) | Bluetooth Classic | UART | `BLUETOOTH = RN42` | RN-42 | +| [Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) | Bluetooth Low Energy | SPI | `BLUETOOTH = AdafruitBLE` | nRF51822 | + +まだサポートされていませんが、可能性のあるもの: +* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479)。[tmk 実装がおそらく見つかります](https://github.com/tmk/tmk_keyboard/issues/514) +* RN-42 ファームウェアが書き込まれた HC-05 ボード。どちらも明らかに CSR BC417 チップを使っています。RN-42 ファームウェアを使って書き込むと、HID 機能が提供されます。 +* Sparkfun Bluetooth Mate +* HM-13 ベースのボード + +### Adafruit BLE SPI Friend +現在のところ QMK によってサポートされている唯一の bluetooth チップセットは、Adafruit Bluefruit SPI Friend です。Adafruit のカスタムファームウェアを実行する Nordic nRF5182 ベースのチップです。データは Hardware SPI を介した Adafruit の SDEP を使って転送されます。[Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) は Adafruit ファームウェアを搭載した Nordic BLE チップに SPI 経由で接続された AVR mcu であるため、サポートされます。SPI friend を使ってカスタムボードを構築する場合、32u4 feather が使用するピン選択を使うのが最も簡単ですが、以下の定義で config.h オプションでピンを変更することができます: +* #define AdafruitBleResetPin D4 +* #define AdafruitBleCSPin B4 +* #define AdafruitBleIRQPin E6 + +Bluefruit UART friend は SPI friend に変換することができますが、これにはMDBT40 チップへの直接の再書き込みとはんだ付けが[必要です](https://github.com/qmk/qmk_firmware/issues/2274)。 + + +## Bluetooth の Rules.mk オプション + +現在サポートされている Bluetooth チップセットは [N-キーロールオーバー (NKRO)](ja/reference_glossary.md#n-key-rollover-nkro) をサポートしていません。そのため、`rules.mk` に `NKRO_ENABLE = no` を含めなければなりません。 + +Bluetooth を有効にするには、以下のうちの1つだけを使ってください: +* BLUETOOTH_ENABLE = yes (レガシーオプション) +* BLUETOOTH = RN42 +* BLUETOOTH = AdafruitBLE + +## Bluetooth キーコード + +これは複数のキーボードの出力が選択できる場合に使われます。現在のところ、これは USB と Bluetooth の両方をサポートするキーボードで、それらの間の切り替えのみが可能です。 + +| 名前 | 説明 | +| ---------- | ------------------------------------- | +| `OUT_AUTO` | USB と Bluetooth を自動的に切り替える | +| `OUT_USB` | USB のみ | +| `OUT_BT` | Bluetooth のみ | diff --git a/ja/feature_bootmagic.md b/ja/feature_bootmagic.md new file mode 100644 index 00000000000..20a93d5c448 --- /dev/null +++ b/ja/feature_bootmagic.md @@ -0,0 +1,182 @@ +# ブートマジック + + + +再書き込みせずにキーボードの挙動を変更することができる、3つの独立した関連する機能があります。それぞれは似たような機能を持ちますが、キーボードがどのように設定されているかによって異なる方法でアクセスされます。 + +**ブートマジック**は初期化の間にキーボードを設定するためのシステムです。ブートマジックコマンドを起動するには、ブートマジックキーと1つ以上のコマンドキーを押し続けます。 + +**ブートマジックキーコード** は前に `MAGIC_` が付いており、キーボードが初期化された*後で*ブートマジックの機能にアクセスすることができます。キーコードを使うには、他のキーコードと同じようにそれらをキーマップに割り当てます。 + +以前は**マジック**として知られていた**コマンド**は、キーボードの異なる側面を制御することができる別の機能です。ブートマジックと一部の機能を共有しますが、コンソールにバージョン情報を出力するような、ブートマジックにはできないこともできます。詳細は、[コマンド](ja/feature_command.md)を見てください。 + +一部のキーボードでは、ブートマジックはデフォルトで無効になっています。その場合、`rules.mk` 内で以下のように明示的に有効にする必要があります: + +```make +BOOTMAGIC_ENABLE = full +``` + +?> `full` の代わりに `yes` が使われていることがあるかもしれませんが、これは問題ありません。ただし、`yes` は非推奨で、理想的には `full` (あるいは`lite`) が使われるべきです。 + +さらに、以下を `rules.mk` ファイルに追加することで、[ブートマジックライト](#bootmagic-lite) (スケールダウンした、とても基本的なバージョンのブートマジック)を使うことができます: + +```make +BOOTMAGIC_ENABLE = lite +``` + +## ホットキー + +キーボードを接続しながら、ブートマジックキー(デフォルトはスペース)と目的のホットキーを押します。例えば、スペースと `B` を押したままにすると、ブートローダに入ります。 + +| ホットキー | 説明 | +|------------------|---------------------------------------------| +| エスケープ | EEPROM のブートマジック設定を無視する | +| `B` | ブートローダに入る | +| `D` | シリアルを介するデバッグ出力の切り替え | +| `X` | キーマトリックスのデバッグ出力の切り替え | +| `K` | キーボードのデバッグの切り替え | +| `M` | マウスのデバッグの切り替え | +| `L` | EE_HANDS 左右設定に、"左手"を設定 | +| `R` | EE_HANDS 左右設定に、"右手"を設定 | +| Backspace | EEPROM をクリア | +| Caps Lock | Caps Lock を左コントロールとして扱うかを切り替え | +| 左 Control | Caps Lock と左コントロールの入れ替えを切り替え | +| 左 Alt | 左 Alt と左 GUI の入れ替えを切り替え | +| 右 Alt | 右 Alt と右 GUI の入れ替えを切り替え | +| 左 GUI | GUI キーの有効・無効を切り替え (ゲームの時に便利です) | +| ` | ` とエスケープの入れ替えを切り替え | +| `\` | `\` とバックスペースの入れ替えを切り替え | +| `N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | +| `0` | レイヤー 0 をデフォルトレイヤーにする | +| `1` | レイヤー 1 をデフォルトレイヤーにする | +| `2` | レイヤー 2 をデフォルトレイヤーにする | +| `3` | レイヤー 3 をデフォルトレイヤーにする | +| `4` | レイヤー 4 をデフォルトレイヤーにする | +| `5` | レイヤー 5 をデフォルトレイヤーにする | +| `6` | レイヤー 6 をデフォルトレイヤーにする | +| `7` | レイヤー 7 をデフォルトレイヤーにする | + +## キーコード :id=keycodes + +| キー | エイリアス | 説明 | +|----------------------------------|---------|--------------------------------------------------------------------------| +| `MAGIC_SWAP_CONTROL_CAPSLOCK` | `CL_SWAP` | Caps Lock と左コントロールの入れ替え | +| `MAGIC_UNSWAP_CONTROL_CAPSLOCK` | `CL_NORM` | Caps Lock と左コントロールの入れ替えの解除 | +| `MAGIC_CAPSLOCK_TO_CONTROL` | `CL_CTRL` | Caps Lock をコントロールとして扱う | +| `MAGIC_UNCAPSLOCK_TO_CONTROL` | `CL_CAPS` | Caps Lock をコントロールとして扱うことを止める | +| `MAGIC_SWAP_LCTL_LGUI` | `LCG_SWP` | 左コントロールと GUI の入れ替え | +| `MAGIC_UNSWAP_LCTL_LGUI` | `LCG_NRM` | 左コントロールと GUI の入れ替えを解除 | +| `MAGIC_SWAP_RCTL_RGUI` | `RCG_SWP` | 右コントロールと GUI の入れ替え | +| `MAGIC_UNSWAP_RCTL_RGUI` | `RCG_NRM` | 右コントロールと GUI の入れ替えを解除 | +| `MAGIC_SWAP_CTL_GUI` | `CG_SWAP` | 両側のコントロールと GUI の入れ替え | +| `MAGIC_UNSWAP_CTL_GUI` | `CG_NORM` | 両側のコントロールと GUI の入れ替えを解除 | +| `MAGIC_TOGGLE_CTL_GUI` | `CG_TOGG` | 両側のコントロールと GUI の入れ替えの切り替え | +| `MAGIC_SWAP_LALT_LGUI` | `LAG_SWP` | 左 Alt と GUI の入れ替え | +| `MAGIC_UNSWAP_LALT_LGUI` | `LAG_NRM` | 左 Alt と GUI の入れ替えを解除 | +| `MAGIC_SWAP_RALT_RGUI` | `RAG_SWP` | 右 Alt と GUI の入れ替え | +| `MAGIC_UNSWAP_RALT_RGUI` | `RAG_NRM` | 右 Alt と GUI の入れ替えを解除 | +| `MAGIC_SWAP_ALT_GUI` | `AG_SWAP` | 両側の Alt と GUI の入れ替え | +| `MAGIC_UNSWAP_ALT_GUI` | `AG_NORM` | 両側の Alt と GUI の入れ替えを解除 | +| `MAGIC_TOGGLE_ALT_GUI` | `AG_TOGG` | 両側の Alt と GUI の入れ替えの切り替え | +| `MAGIC_NO_GUI` | `GUI_OFF` | GUI キーを無効にする | +| `MAGIC_UNNO_GUI` | `GUI_ON` | GUI キーを有効にする | +| `MAGIC_SWAP_GRAVE_ESC` | `GE_SWAP` | ` とエスケープの入れ替え | +| `MAGIC_UNSWAP_GRAVE_ESC` | `GE_NORM` | ` とエスケープの入れ替えを解除 | +| `MAGIC_SWAP_BACKSLASH_BACKSPACE` | `BS_SWAP` | `\` とバックスペースを入れ替え | +| `MAGIC_UNSWAP_BACKSLASH_BACKSPACE` | `BS_NORM` | `\` とバックスペースの入れ替えを解除する | +| `MAGIC_HOST_NKRO` | `NK_ON` | N キーロールオーバーを有効にする | +| `MAGIC_UNHOST_NKRO` | `NK_OFF` | N キーロールオーバーを無効にする | +| `MAGIC_TOGGLE_NKRO` | `NK_TOGG` | N キーロールオーバーの有効・無効を切り替え | +| `MAGIC_EE_HANDS_LEFT` | `EH_LEFT` | 分割キーボードのマスター側を左手に設定(`EE_HANDS` 用) | +| `MAGIC_EE_HANDS_RIGHT` | `EH_RGHT` | 分割キーボードのマスター側を右手に設定(`EE_HANDS` 用) | + +## 設定 + +ブートマジックのためのホットキーの割り当てを変更したい場合は、キーボードあるいはキーマップレベルのどちらかで、`config.h` にこれらを `#define` します。 + +| 定義 | デフォルト | 説明 | +|----------------------------------------|-------------|---------------------------------------------------| +| `BOOTMAGIC_KEY_SALT` | `KC_SPACE` | ブートマジックキー | +| `BOOTMAGIC_KEY_SKIP` | `KC_ESC` | EEPROM のブートマジック設定を無視する | +| `BOOTMAGIC_KEY_EEPROM_CLEAR` | `KC_BSPACE` | EEPROM 設定をクリアする | +| `BOOTMAGIC_KEY_BOOTLOADER` | `KC_B` | ブートローダに入る | +| `BOOTMAGIC_KEY_DEBUG_ENABLE` | `KC_D` | シリアルを介するデバッグ出力の切り替え | +| `BOOTMAGIC_KEY_DEBUG_MATRIX` | `KC_X` | マトリックスのデバッグを切り替え | +| `BOOTMAGIC_KEY_DEBUG_KEYBOARD` | `KC_K` | キーボードのデバッグの切り替え | +| `BOOTMAGIC_KEY_DEBUG_MOUSE` | `KC_M` | マウスのデバッグの切り替え | +| `BOOTMAGIC_KEY_EE_HANDS_LEFT` | `KC_L` | EE_HANDS 左右設定に、"左手"を設定 | +| `BOOTMAGIC_KEY_EE_HANDS_RIGHT` | `KC_R` | EE_HANDS 左右設定に、"右手"を設定 | +| `BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK` | `KC_LCTRL` | 左コントロールと Caps Lock の入れ替え | +| `BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL` | `KC_CAPSLOCK` | Caps Lock を左コントロールとして扱うかを切り替え | +| `BOOTMAGIC_KEY_SWAP_LALT_LGUI` | `KC_LALT` | 左 Alt と左 GUI の入れ替えを切り替え (macOS 用) | +| `BOOTMAGIC_KEY_SWAP_RALT_RGUI` | `KC_RALT` | 右 Alt と右 GUI の入れ替えを切り替え (macOS 用) | +| `BOOTMAGIC_KEY_NO_GUI` | `KC_LGUI` | GUI キーの有効・無効を切り替え (ゲームの時に便利です) | +| `BOOTMAGIC_KEY_SWAP_GRAVE_ESC` | `KC_GRAVE` | ` とエスケープの入れ替えを切り替え | +| `BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE` | `KC_BSLASH` | `\` とバックスペースの入れ替えを切り替え | +| `BOOTMAGIC_HOST_NKRO` | `KC_N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_0` | `KC_0` | レイヤー 0 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_1` | `KC_1` | レイヤー 1 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_2` | `KC_2` | レイヤー 2 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_3` | `KC_3` | レイヤー 3 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_4` | `KC_4` | レイヤー 4 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_5` | `KC_5` | レイヤー 5 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_6` | `KC_6` | レイヤー 6 をデフォルトレイヤーにする | +| `BOOTMAGIC_KEY_DEFAULT_LAYER_7` | `KC_7` | レイヤー 7 をデフォルトレイヤーにする | + +# ブートマジックライト :id=bootmagic-lite + +本格的なブートマジック機能の他に、ブートローダへのジャンプのみを処理するブートマジックライトがあります。これは、物理的なリセットボタンが無くブートローダにジャンプする方法が必要だが、ブートマジックが引き起こす問題を扱いたくないキーボードに適しています。 + +ブートマジックのこのバージョンを有効にするには、以下を使って `rules.mk` で有効にする必要があります: + +```make +BOOTMAGIC_ENABLE = lite +``` + +さらに、どのキーを使うかを指定したほうが良いかもしれません。これは普通ではないマトリックスを持つキーボードで特に便利です。そのためには、使いたいキーの行と列を指定する必要があります。`config.h` ファイルにこれらのエントリを追加します: + +```c +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 1 +``` + +デフォルトでは、これらは 0 と 0 に設定されます。これは通常はほとんどのキーボードで "ESC" キーです。 + +ブートローダを起動するには、キーボードを接続する時にこのキーを押し続けます。たった1つのキーです。 + +!> ブートマジックライトを使用すると、EEPROM を**常にリセットします**。つまり保存された全ての設定は失われます。 + +## 分割キーボード + +`SPLIT_HAND_PIN` のようなオプションで、左右の設定があらかじめ決められている場合は、キーボードの左右で別のキーを設定する必要があるかもしれません。これを行うには、`config.h` ファイルに以下のエントリを追加します。 + +```c +#define BOOTMAGIC_LITE_ROW_RIGHT 4 +#define BOOTMAGIC_LITE_COLUMN_RIGHT 1 +``` + +デフォルトでは、これらの値は設定されていません。 + +## 高度なブートマジックライト + +`bootmagic_lite` 関数は必要に応じてコード内で置き換えることができるように、弱く定義されています。これの良い例は Zeal60 キーボードで、追加の処理が必要です。 + +関数を置き換えるには、以下のようなものをコードに追加するだけです: + +```c +void bootmagic_lite(void) { + matrix_scan(); + wait_ms(DEBOUNCE * 2); + matrix_scan(); + + if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { + // ブートローダにジャンプする。 + bootloader_jump(); + } +} +``` + +追加の機能をここに追加することができます。例えば、eeprom のリセットやブートマジックを起動するために押す必要がある追加のキーです。`bootmagic_lite` はファームウェア内で大部分の機能が初期化される前に呼ばれることに注意してください。 diff --git a/ja/feature_combo.md b/ja/feature_combo.md new file mode 100644 index 00000000000..bd46e88b7fa --- /dev/null +++ b/ja/feature_combo.md @@ -0,0 +1,108 @@ +# コンボ + + + +コンボ機能は、同時押し方式でのカスタムアクション追加機能です。同時に複数のキーを押して、異なる効果を生み出すことができます。例えば、タッピング時間内で `A` と `S` を押すと、代わりに `ESC` が押されます。もっと複雑なタスクを実行させることもできます。 + +この機能を有効にするには、`rules.mk` に `COMBO_ENABLE = yes` を追加する必要があります。 + +さらに、使用するコンボの数を `config.h` の中で、`#define COMBO_COUNT 1` (1を使用するコンボの数で置き換えます)と書いて、指定する必要があります。 + + +また、デフォルトでは、コンボのタッピング時間は `TAPPING_TERM` と同じ値に設定されます (ほとんどのキーボードではデフォルトで 200)。ただし、`config.h` で定義することにより異なる値を指定することができます。例えば: `#define COMBO_TERM 300` はコンボのためのタイムアウト時間を 300ms に設定します。 + +次に、`keymap.c` ファイルに、`COMBO_END` で終了するキーのシーケンス、およびキーの組み合わせを列挙する構造体、その結果のアクションを定義する必要があります。 + +```c +const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END}; +combo_t key_combos[COMBO_COUNT] = {COMBO(test_combo, KC_ESC)}; +``` + +これは、A と B のキーを押した場合に、"Escape" を送信します。 + +!> このメソッドは[基本的なキーコード](ja/keycodes_basic.md)のみをサポートします。詳細な制御については例を見てください。 + +## 例 + +リストを追加したい場合は、以下のようなものを使います: + +```c +enum combos { + AB_ESC, + JK_TAB +}; + +const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; +const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [AB_ESC] = COMBO(ab_combo, KC_ESC), + [JK_TAB] = COMBO(jk_combo, KC_TAB) +}; +``` + +より複雑な実装として、カスタム処理を追加するために `process_combo_event` 関数を使うことができます。 + +```c +enum combo_events { + ZC_COPY, + XV_PASTE +}; + +const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END}; +const uint16_t PROGMEM paste_combo[] = {KC_X, KC_V, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [ZC_COPY] = COMBO_ACTION(copy_combo), + [XV_PASTE] = COMBO_ACTION(paste_combo), +}; + +void process_combo_event(uint16_t combo_index, bool pressed) { + switch(combo_index) { + case ZC_COPY: + if (pressed) { + tap_code16(LCTL(KC_C)); + } + break; + case XV_PASTE: + if (pressed) { + tap_code16(LCTL(KC_V)); + } + break; + } +} +``` + +これは、Z と C を押すと Ctrl+C を送信し、X と V を押すと Ctrl+V を送信します。これを変更して、レイヤーの変更、サウンドの再生、設定の変更などを行うこともできます。 + +## 追加の設定 + +長いコンボあるいはさらに長いコンボを使っている場合、構造体があなたのしていることに対応するのに十分な大きさで無いかもしれないため、問題が発生するかもしれません。 + +この場合、`config.h` ファイルに `#define EXTRA_LONG_COMBOS` または `#define EXTRA_EXTRA_LONG_COMBOS` のどちらかを追加することができます。 + +`COMBO_ALLOW_ACTION_KEYS` を定義することでアクションキーを有効にすることもできます。 + +## キーコード + +その場でコンボ機能を有効、無効および切り替えすることができます。ゲームなどで、一時的にそれらを無効にする必要がある場合に便利です。 + +| キーコード | 説明 | +|----------|---------------------------------| +| `CMB_ON` | コンボ機能をオンにします | +| `CMB_OFF` | コンボ機能をオフにします | +| `CMB_TOG` | コンボ機能のオンとオフを切り替えます | + +## ユーザコールバック + +キーコードに加えて、状態を設定または状態をチェックするために使うことができる幾つかの関数があります: + +| 関数 | 説明 | +|-----------|--------------------------------------------------------------------| +| `combo_enable()` | コンボ機能を有効にします | +| `combo_disable()` | コンボ機能を無効にし、コンボバッファをクリアします | +| `combo_toggle()` | コンボ機能の状態を切り替えます | +| `is_combo_enabled()` | コンボ機能の状態(true か false)を返します | diff --git a/ja/feature_command.md b/ja/feature_command.md new file mode 100644 index 00000000000..f8b7e892941 --- /dev/null +++ b/ja/feature_command.md @@ -0,0 +1,56 @@ +# コマンド + + + +コマンド(旧称:マジック)は、ファームウェアを書き込んだり、[ブートマジック](ja/feature_bootmagic.md)を使うためにプラグを抜いたりすることなくキーボードの挙動を変更する方法です。この機能と[ブートマジックキーコード](feature_bootmagic.md#keycodes)には多くの重複があります。可能な限り、コマンドでは無くブートマジックキーコードの機能を使うことをお勧めします。 + +一部のキーボードではコマンドがデフォルトで無効になっています。その場合、`rules.mk` 内で明示的に有効にする必要があります: + +```make +COMMAND_ENABLE = yes +``` + +## 使用法 + +コマンドを使うには、`IS_COMMAND()` マクロで定義されたキーの組み合わせを押し続けます。デフォルトでは、これは「左Shift + 右Shift」です。次に、目的のコマンドに対応するキーを押します。例えば、現在の QMK バージョンを QMK Toolbox コンソールに出力するには、「左Shift + 右Shift + `V`」を押します。 + +## 設定 + +コマンドのためのキーの割り当てを変更したい場合は、キーボードあるいはキーマップレベルのどちらかで、`config.h` にこれらを `#define` します。ここで割り当てる全てのキーコードは `KC_` 接頭辞を省略する必要があります。 + +| 定義 | デフォルト | 説明 | +|------------------------------------|--------------------------------|------------------------------------------------| +| `IS_COMMAND()` | `(get_mods() == MOD_MASK_SHIFT)` | コマンドをアクティブにするキーの組み合わせ | +| `MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` | `true` | ファンクション行を使ってデフォルトレイヤーを設定 | +| `MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` | `true` | 数字キーでデフォルトレイヤーを設定 | +| `MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM` | `false` | `MAGIC_KEY_LAYER0..9` を使ってデフォルトレイヤーを設定 | +| `MAGIC_KEY_DEBUG` | `D` | シリアルを介するデバッグの切り替え | +| `MAGIC_KEY_DEBUG_MATRIX` | `X` | キーマトリックスのデバッグの切り替え | +| `MAGIC_KEY_DEBUG_KBD` | `K` | キーボードのデバッグの切り替え | +| `MAGIC_KEY_DEBUG_MOUSE` | `M` | マウスのデバッグの切り替え | +| `MAGIC_KEY_CONSOLE` | `C` | コマンドコンソールを有効にする | +| `MAGIC_KEY_VERSION` | `V` | コンソールに実行中の QMK バージョンを出力 | +| `MAGIC_KEY_STATUS` | `S` | コンソールに現在のキーボードの状態を出力 | +| `MAGIC_KEY_HELP` | `H` | コンソールにコマンドのヘルプを出力 | +| `MAGIC_KEY_HELP_ALT` | `SLASH` | コンソールにコマンドのヘルプを出力 (代替) | +| `MAGIC_KEY_LAYER0` | `0` | レイヤー 0 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER0_ALT` | `GRAVE` | レイヤー 0 をデフォルトレイヤーにする (代替) | +| `MAGIC_KEY_LAYER1` | `1` | レイヤー 1 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER2` | `2` | レイヤー 2 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER3` | `3` | レイヤー 3 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER4` | `4` | レイヤー 4 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER5` | `5` | レイヤー 5 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER6` | `6` | レイヤー 6 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER7` | `7` | レイヤー 7 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER8` | `8` | レイヤー 8 をデフォルトレイヤーにする | +| `MAGIC_KEY_LAYER9` | `9` | レイヤー 9 をデフォルトレイヤーにする | +| `MAGIC_KEY_BOOTLOADER` | `B` | ブートローダにジャンプする | +| `MAGIC_KEY_BOOTLOADER_ALT` | `ESC` | ブートローダにジャンプする (代替) | +| `MAGIC_KEY_LOCK` | `CAPS` | 何も入力できないようにキーボードをロック | +| `MAGIC_KEY_EEPROM` | `E` | 保存された EEPROM 設定をコンソールに出力 | +| `MAGIC_KEY_EEPROM_CLEAR` | `BSPACE` | EEPROM をクリア | +| `MAGIC_KEY_NKRO` | `N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | +| `MAGIC_KEY_SLEEP_LED` | `Z` | コンピュータがスリープの時に LED を切り替え | diff --git a/ja/feature_debounce_type.md b/ja/feature_debounce_type.md new file mode 100644 index 00000000000..2d874b7565c --- /dev/null +++ b/ja/feature_debounce_type.md @@ -0,0 +1,47 @@ +# デバウンスアルゴリズム + + + +QMK はデバウンス API を介して複数のデバウンスアルゴリズムをサポートします。 + +どのデバウンスメソッドが呼ばれるかのロジックは下記のとおりです。rules.mk で設定された様々な定義をチェックします。 + +``` +DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce +DEBOUNCE_TYPE?= sym_g +ifneq ($(strip $(DEBOUNCE_TYPE)), custom) + QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c +endif +``` + +# デバウンスの選択 + +| DEBOUNCE_TYPE | 説明 | 他に必要なもの | +| ------------- | --------------------------------------------------- | ----------------------------- | +| 未定義 | デフォルトのアルゴリズム、現在のところ sym_g を使います | 無し | +| custom | 独自のデバウンスコードを使います | ```SRC += debounce.c``` で独自の debounce.c を追加し、必要な関数を実装します | +| anything_else | quantum/debounce/* から他のアルゴリズムを使います | 無し | + +**分割キーボードについて**: +デバウンスコードは分割キーボードと互換性があります。 + +# 独自のデバウンスコードの使用 +* ```DEBOUNCE_TYPE = custom``` を設定します。 +* ```SRC += debounce.c``` を追加します。 +* 独自の ```debounce.c``` を追加します。例については、```quantum/debounce``` にある現在の実装をみてください。 +* 毎回のマトリクススキャンの結果はその度デバウンスによって処理されます。 +* MATRIX_ROWS ではなく num_rows を使って、分割キーボードが正しくサポートされるようにします。 + +# インクルードされているデバウンスメソッド間での切り替え +独自の debounce.c をインクルードすることで独自のコードを使うか、またはインクルードされている他のコードに切り替えることができます。 +含まれるデバウンスメソッドは以下の通りです: +* eager_pr - 行ごとにデバウンスします。状態が変化すると、応答は即座に行われ、その後その行は ```DEBOUNCE``` ミリ秒の間入力されません。 +```NUM_KEYS``` の 8ビットカウンタの更新に高い計算コストがかかる、もしくは低スキャンレートのキーボード用で、各指は通常一度に1行しか叩かないようになっています。これは ErgoDox モデルに適しています; マトリックスは90度回転しているため、その「行」は実際には「列」であり、通常の使用では各指は一度に1つの「行」にしか当たりません。 +* eager_pk - キーごとにデバウンスします。状態が変化すると、応答は即座に行われ、その後そのキーは ```DEBOUNCE``` ミリ秒の間入力されません。 +* sym_g - キーボードごとにデバウンスします。状態が変化すると、グローバルタイマが設定されます。```DEBOUNCE``` ミリ秒の間何も変化がなければ、全ての入力の変更がプッシュされます。 +* sym_pk - キーごとにデバウンスします。状態が変化すると、キーごとのタイマーが設定されます。```DEBOUNCE``` ミリ秒の間そのキーに変化がなければ、キーの状態の変更がプッシュされます。 + + diff --git a/ja/feature_dip_switch.md b/ja/feature_dip_switch.md new file mode 100644 index 00000000000..a0f6aeb0035 --- /dev/null +++ b/ja/feature_dip_switch.md @@ -0,0 +1,109 @@ +# DIP スイッチ + + + +DIP スイッチは、以下を `rules.mk` に追加することでサポートされます: + + DIP_SWITCH_ENABLE = yes + +さらに、以下を `config.h` に追加します: + +```c +// Connects each switch in the dip switch to the GPIO pin of the MCU +#define DIP_SWITCH_PINS { B14, A15, A10, B9 } +``` + +あるいは + +```c +// Connect each switch in the DIP switch to an unused intersections in the key matrix. +#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs +``` + +## コールバック + +コールバック関数を `.c` に記述することができます: + +```c +void dip_switch_update_kb(uint8_t index, bool active) { + dip_switch_update_user(index, active); +} +``` + + +あるいは `keymap.c` に記述することもできます: + +```c +void dip_switch_update_user(uint8_t index, bool active) { + switch (index) { + case 0: + if(active) { audio_on(); } else { audio_off(); } + break; + case 1: + if(active) { clicky_on(); } else { clicky_off(); } + break; + case 2: + if(active) { music_on(); } else { music_off(); } + break; + case 3: + if (active) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_song); + #endif + layer_on(_PLOVER); + } else { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + break; + } +} +``` + +更に、より複雑な処理ができるビットマスク関数をサポートします。 + + +```c +void dip_switch_update_mask_kb(uint32_t state) { + dip_switch_update_mask_user(state); +} +``` + + +あるいは `keymap.c` に記述することもできます: + +```c +void dip_switch_update_mask_user(uint32_t state) { + if (state & (1UL<<0) && state & (1UL<<1)) { + layer_on(_ADJUST); // C on esc + } else { + layer_off(_ADJUST); + } + if (state & (1UL<<0)) { + layer_on(_TEST_A); // A on ESC + } else { + layer_off(_TEST_A); + } + if (state & (1UL<<1)) { + layer_on(_TEST_B); // B on esc + } else { + layer_off(_TEST_B); + } +} +``` + + +## ハードウェア + +### DIP スイッチの各スイッチを MCU の GPIO ピンに接続する + +DIP スイッチの片側は MCU のピンへ直接配線し、もう一方の側はグラウンドに配線する必要があります。機能的に同じであるため、どちら側がどちらに接続されているかは問題にはならないはずです。 + +### DIP スイッチの各スイッチをキーマトリクスの未使用の交点に接続する + +キースイッチと同じように、ダイオードと DIP スイッチが ROW 線と COL 線に接続します。 diff --git a/ja/feature_dynamic_macros.md b/ja/feature_dynamic_macros.md new file mode 100644 index 00000000000..951b9031276 --- /dev/null +++ b/ja/feature_dynamic_macros.md @@ -0,0 +1,71 @@ +# 動的マクロ: ランタイムでのマクロの記録および再生 + + + +QMK はその場で作られた一時的なマクロをサポートします。これらを動的マクロと呼びます。それらはユーザがキーボードから定義し、キーボードのプラグを抜くか再起動すると失われます。 + +1つまたは2つのマクロに合計128のキー押下を保存できます。RAM をより多く使用してサイズを増やすことができます。 + +有効にするには、最初に `rules.mk` に `DYNAMIC_MACRO_ENABLE = yes` を記述します。そして、以下のキーをキーマップに追加します: + +| キー | Alias | 説明 | +|------------------|----------|---------------------------------------------------| +| `DYN_REC_START1` | `DM_REC1` | マクロ 1 の記録を開始します | +| `DYN_REC_START2` | `DM_REC2` | マクロ 2 の記録を開始します | +| `DYN_MACRO_PLAY1` | `DM_PLY1` | マクロ 1 を再生します | +| `DYN_MACRO_PLAY2` | `DM_PLY2` | マクロ 2 を再生します | +| `DYN_REC_STOP` | `DM_RSTP` | 現在記録中のマクロの記録を終了します。 | + +これが必要な全てです。 + +マクロの記録を開始するには、`DYN_REC_START1` または `DYN_REC_START2` のどちらかを押します。 + +記録を終了するには、`DYN_REC_STOP` レイヤーボタンを押します。`DYN_REC_START1` または `DYN_REC_START2` をもう一度押すことでも記録を終了することができます。 + +マクロを再生するには、`DYN_MACRO_PLAY1` あるいは `DYN_MACRO_PLAY2` のどちらかを押します。 + +マクロの一部としてマクロを再生することができます。マクロ 1 を記録中にマクロ 2 を再生、またはその逆も問題ありません。ただし、再帰的なマクロ、つまりマクロ 1 を再生するマクロ 1 は作成しないでください。もしそうしてキーボードが反応しなくなった場合は、キーボードを取り外し再び接続します。これを完全に無効にするには、`config.h` ファイルで `DYNAMIC_MACRO_NO_NESTING` を定義します。 + +?> 動的マクロの内部の詳細については、`process_dynamic_macro.h` および `process_dynamic_macro.c` ファイルのコメントを読んでください。 + +## カスタマイズ + +ある程度のカスタマイズを可能にするオプションがいくつか追加されています。 + +| 定義 | デフォルト | 説明 | +|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| +| `DYNAMIC_MACRO_SIZE` | 128 | 動的マクロが使用できるメモリ量を設定します。これは限られたリソースであり、コントローラに依存します。 | +| `DYNAMIC_MACRO_USER_CALL` | *定義なし* | これを定義すると、ユーザの `keymap.c` ファイルを使ってマクロが起動されます。 | +| `DYNAMIC_MACRO_NO_NESTING` | *定義なし* | これを定義すると、別のマクロからマクロを呼び出す(入れ子になったマクロ)機能を無効にします。 | + + +記録中にキーを押すたびに LED が点滅し始めた場合は、マクロバッファにマクロを入れるスペースがもう無いことを意味します。マクロを入れるには、他のマクロ(それらは同じバッファを共有します)を短くするか、`config.h` に `DYNAMIC_MACRO_SIZE` 定義を追加することでバッファを増やします(デフォルト値: 128; ヘッダ内のコメントを読んでください)。 + + +### DYNAMIC_MACRO_USER_CALL + +以前のバージョンの動的マクロをお使いの方へ: 専用の `DYN_REC_STOP` キーを使わずに動的マクロキーへのアクセスに使われるレイヤーモディファイアのみを使って、マクロの記録を終了することもまだ可能です。この動作に戻したい場合は、`#define DYNAMIC_MACRO_USER_CALL` を `config.h` に追加し、以下のスニペットを `process_record_user()` 関数の先頭に記述します: + +```c + uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode); + + if (!process_record_dynamic_macro(macro_kc, record)) { + return false; + } +``` + +### ユーザフック + +カスタム機能とフィードバックオプションを動的マクロ機能に追加するために使うことができるフックが幾つかあります。これによりある程度のカスタマイズが可能になります。 + +direction がどのマクロであるかを示すことに注意してください。`1` がマクロ 1、`-1` がマクロ 2、0 がマクロ無しです。 + +* `dynamic_macro_record_start_user(void)` - マクロの記録を開始する時に起動されます。 +* `dynamic_macro_play_user(int8_t direction)` - マクロを再生する時に起動されます。 +* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - マクロの記録中に各キー押下で起動されます。 +* `dynamic_macro_record_end_user(int8_t direction)` - マクロの記録を停止した時に起動されます。 + +さらに、動的マクロ機能が有効な場合にバックライトを点滅させるために `dynamic_macro_led_blink()` を呼び出すことができます。 diff --git a/ja/feature_encoders.md b/ja/feature_encoders.md new file mode 100644 index 00000000000..7b7f394c83f --- /dev/null +++ b/ja/feature_encoders.md @@ -0,0 +1,81 @@ +# エンコーダ + + + +以下を `rules.mk` に追加することで基本的なエンコーダがサポートされます: + +```make +ENCODER_ENABLE = yes +``` + +さらに、以下を `config.h` に追加します: + +```c +#define ENCODERS_PAD_A { B12 } +#define ENCODERS_PAD_B { B13 } +``` + +各 PAD_A/B 変数は配列を定義するため、複数のエンコーダを定義することができます。例えば: + +```c +#define ENCODERS_PAD_A { encoder1a, encoder2a } +#define ENCODERS_PAD_B { encoder1b, encoder2b } +``` + +エンコーダの時計回りの方向が間違っている場合は、A と B のパッド定義を交換することができます。define を使って逆にすることもできます: + +```c +#define ENCODER_DIRECTION_FLIP +``` + +さらに、エンコーダが各戻り止め(デテント)間に登録するパルス数を定義する解像度は、次のように定義できます: + +```c +#define ENCODER_RESOLUTION 4 +``` + +## 分割キーボード + +分割キーボードのそれぞれの側のエンコーダに異なるピン配列を使っている場合、右側のピン配列を以下のように定義することができます: + +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + +## コールバック + +コールバック関数を `.c` に記述することができます: + +```c +void encoder_update_kb(uint8_t index, bool clockwise) { + encoder_update_user(index, clockwise); +} +``` + +あるいは `keymap.c` に記述することもできます: + +```c +void encoder_update_user(uint8_t index, bool clockwise) { + if (index == 0) { /* First encoder */ + if (clockwise) { + tap_code(KC_PGDN); + } else { + tap_code(KC_PGUP); + } + } else if (index == 1) { /* Second encoder */ + if (clockwise) { + tap_code(KC_DOWN); + } else { + tap_code(KC_UP); + } + } +} +``` + +## ハードウェア + +エンコーダの A と B の線は MCU に直接配線し、C/common 線はグランドに配線する必要があります。 diff --git a/ja/feature_grave_esc.md b/ja/feature_grave_esc.md new file mode 100644 index 00000000000..8c6680d74d7 --- /dev/null +++ b/ja/feature_grave_esc.md @@ -0,0 +1,37 @@ +# グレイブエスケープ + + + +60% キーボード、またはファンクションキー行の無い他のレイアウトを使っている場合、専用の Escape キーが無いことに気付くでしょう。グレイブエスケープは grave キー (` および `~`) を Escape と共有することができる機能です。 + +## 使用法 + +キーマップ内の `KC_GRAVE` キー (通常は`1` キーの左)を `KC_GESC` に置き換えます。ほとんどの場合、このキーは押された時に `KC_ESC` を出力します。ただし、Shift あるいは GUI を押したままにすると、代わりに `KC_GRV` を出力します。 + +## OS に見えるもの + +メアリーがキーボードで GESC を押すと、OS には KC_ESC 文字が見えます。メアリーが Shift を押しながら GESC を押すと、`~` または Shift された時はバッククォートを出力します。彼女が GUI/CMD/WIN を押したままにすると、1つの ` 文字を出力します。 + +## キーコード + +| キー | エイリアス | 説明 | +|---------|-----------|------------------------------------------------------------------| +| `KC_GESC` | `GRAVE_ESC` | 押された場合に Escape。Shift あるいは GUI が押されたままの場合は ` | + +### 注意事項 + +macOS では、Command+` はデフォルトで "次のウィンドウを操作対象にする" にマップされます。つまりバッククォートを出力しません。さらに、ショートカットがキーボード環境設定で変更された場合でも、ターミナルは常にこのショートカットを認識してウィンドウを切り替えます。 + +## 設定 + +グレイブエスケープが壊す可能性のあるキーの組み合わせが幾つかあります。その中には、Windows では Control+Shift+Escape、macOSでは Command+Option+Escape があります。これを回避するには、`config.h` で以下のオプションを `#define` することができます: + +| 定義 | 説明 | +|--------------------------|-----------------------------------------| +| `GRAVE_ESC_ALT_OVERRIDE` | Alt が押された場合、常に Escape を送信する | +| `GRAVE_ESC_CTRL_OVERRIDE` | Control が押された場合、常に Escape を送信する | +| `GRAVE_ESC_GUI_OVERRIDE` | GUI が押された場合、常に Escape を送信する | +| `GRAVE_ESC_SHIFT_OVERRIDE` | Shift が押された場合、常に Escape を送信する | diff --git a/ja/feature_haptic_feedback.md b/ja/feature_haptic_feedback.md new file mode 100644 index 00000000000..b9b42670147 --- /dev/null +++ b/ja/feature_haptic_feedback.md @@ -0,0 +1,163 @@ +# 触覚フィードバック + + + +## 触覚フィードバック の rules.mk オプション + +現在のところ、`rules.mk` で触覚フィードバック用に以下のオプションを利用可能です: + +`HAPTIC_ENABLE += DRV2605L` + +`HAPTIC_ENABLE += SOLENOID` + +## サポートされる既知のハードウェア + +| 名前 | 説明 | +|--------------------|-------------------------------------------------| +| [LV061228B-L65-A](https://www.digikey.com/product-detail/en/jinlong-machinery-electronics-inc/LV061228B-L65-A/1670-1050-ND/7732325) | z-axis 2v LRA | +| [Mini Motor Disc](https://www.adafruit.com/product/1201) | small 2-5v ERM | + +## 触覚キーコード + +以下のキーコードは、選択した触覚メカニズムに依存して動作するかどうか決まります。 + +| 名前 | 説明 | +|-----------|-------------------------------------------------------| +| `HPT_ON` | 触覚フィードバックをオン | +| `HPT_OFF` | 触覚フィードバックをオフ | +| `HPT_TOG` | 触覚フィードバックのオン/オフを切り替え | +| `HPT_RST` | 触覚フィードバック設定をデフォルトに戻す | +| `HPT_FBK` | キー押下またはリリースまたはその両方でフィードバックを切り替え | +| `HPT_BUZ` | ソレノイドの振動のオン/オフを切り替え | +| `HPT_MODI` | 次の DRV2605L 波形に移動 | +| `HPT_MODD` | 前の DRV2605L 波形に移動 | +| `HPT_CONT` | 連続触覚モードのオン/オフを切り替え | +| `HPT_CONI` | DRV2605L の連続触覚強度を増加 | +| `HPT_COND` | DRV2605L の連続触覚強度を減少 | +| `HPT_DWLI` | ソレノイドの滞留時間を増加 | +| `HPT_DWLD` | ソレノイドの滞留時間を減少 | + +### ソレノイド + +ほとんどの MCU はソレノイドのコイルを駆動するために必要な電流を供給できないため、最初に MOSFET を介してソレノイドを駆動する回路を構築する必要があります。 + +[Adafruit が提供する配線図](https://playground.arduino.cc/uploads/Learning/solenoid_driver.pdf) + + +| 設定 | デフォルト | 説明 | +|--------------------------|---------------|-------------------------------------------------------| +| `SOLENOID_PIN` | *定義なし* | ソレノイドが接続されているピンを設定する。 | +| `SOLENOID_DEFAULT_DWELL` | `12` ms | ソレノイドのデフォルトの滞留時間を設定する。 | +| `SOLENOID_MIN_DWELL` | `4` ms | 滞留時間の下限を設定する。 | +| `SOLENOID_MAX_DWELL` | `100` ms | 滞留時間の上限を設定する。 | + +?> 滞留時間とは、「プランジャー」が作動したままになる時間です。滞留時間により、ソレノイドの音が変わります。 + +ブートローダ実行中に一部のピンが給電されているかもしれず (例えば、STM32F303 チップ上の A13)、そうすると書き込みプロセスの間ずっとソレノイドがオン状態になることに注意してください。これはソレノイドを加熱し損傷を与えるかもしれません。ソレノイドが接続されているピンがブートローダ/DFU 実行中にソレノイドをオンにしていることが分かった場合は、他のピンを選択してください。 + +### DRV2605L + +DRV2605Lは i2c プロトコルで制御され、SDA および SCL ピンに接続する必要があります。これらは使用する MCU によって異なります。 + +#### フィードバックモータのセットアップ + +このドライバは2つの異なるフィードバックモータをサポートします。選択したモータに基づいて、`config.h` で以下を設定します。 + +##### ERM + +偏心回転質量振動モータ (ERM) は偏りのある重りが取り付けられたモータで、駆動信号が取り付けられると偏りのある重りが回転し、正弦波が振動に変換されます。 + +``` +#define FB_ERM_LRA 0 +#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ +#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ + +/* 特定のモータに最適な設定については、データシートを参照してください。*/ +#define RATED_VOLTAGE 3 +#define V_PEAK 5 +``` +##### LRA + +線形共振アクチュエータ (LRA、線形バイブレータとしても知られています)は、ERM と異なります。LRA は重りと磁石をバネで吊るしたものとボイスコイルで構成されています。駆動信号が印加されるとされると、重りは単一の軸で振動します (左右または上下)。重りはバネに取り付けられているため、特定の周波数で共振効果があります。この周波数は LRA が最も効率的に動作する箇所です。この周波数の推奨範囲については、モータのデータシートを参照してください。 + +``` +#define FB_ERM_LRA 1 +#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ +#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ + +/* 特定のモータに最適な設定については、データシートを参照してください。*/ +#define RATED_VOLTAGE 2 +#define V_PEAK 2.8 +#define V_RMS 2.0 +#define V_PEAK 2.1 +#define F_LRA 205 /* 共振周波数 */ +``` + +#### DRV2605L 波形ライブラリ + +DRV2605L には呼び出して再生できる様々な波形シーケンスのプリロードライブラリが同梱されています。マクロを書く場合、これらの波形は `DRV_pulse(*sequence name or number*)` を使って再生することができます + +データシートの波形シーケンスのリスト + +| seq# | シーケンス名 | seq# | シーケンス名 | seq# | シーケンス名 | +|-----|---------------------|-----|-----------------------------------|-----|--------------------------------------| +| 1 | strong_click | 43 | lg_dblclick_med_60 | 85 | transition_rampup_med_smooth2 | +| 2 | strong_click_60 | 44 | lg_dblsharp_tick | 86 | transition_rampup_short_smooth1 | +| 3 | strong_click_30 | 45 | lg_dblsharp_tick_80 | 87 | transition_rampup_short_smooth2 | +| 4 | sharp_click | 46 | lg_dblsharp_tick_60 | 88 | transition_rampup_long_sharp1 | +| 5 | sharp_click_60 | 47 | buzz | 89 | transition_rampup_long_sharp2 | +| 6 | sharp_click_30 | 48 | buzz_80 | 90 | transition_rampup_med_sharp1 | +| 7 | soft_bump | 49 | buzz_60 | 91 | transition_rampup_med_sharp2 | +| 8 | soft_bump_60 | 50 | buzz_40 | 92 | transition_rampup_short_sharp1 | +| 9 | soft_bump_30 | 51 | buzz_20 | 93 | transition_rampup_short_sharp2 | +| 10 | dbl_click | 52 | pulsing_strong | 94 | transition_rampdown_long_smooth1_50 | +| 11 | dbl_click_60 | 53 | pulsing_strong_80 | 95 | transition_rampdown_long_smooth2_50 | +| 12 | trp_click | 54 | pulsing_medium | 96 | transition_rampdown_med_smooth1_50 | +| 13 | soft_fuzz | 55 | pulsing_medium_80 | 97 | transition_rampdown_med_smooth2_50 | +| 14 | strong_buzz | 56 | pulsing_sharp | 98 | transition_rampdown_short_smooth1_50 | +| 15 | alert_750ms | 57 | pulsing_sharp_80 | 99 | transition_rampdown_short_smooth2_50 | +| 16 | alert_1000ms | 58 | transition_click | 100 | transition_rampdown_long_sharp1_50 | +| 17 | strong_click1 | 59 | transition_click_80 | 101 | transition_rampdown_long_sharp2_50 | +| 18 | strong_click2_80 | 60 | transition_click_60 | 102 | transition_rampdown_med_sharp1_50 | +| 19 | strong_click3_60 | 61 | transition_click_40 | 103 | transition_rampdown_med_sharp2_50 | +| 20 | strong_click4_30 | 62 | transition_click_20 | 104 | transition_rampdown_short_sharp1_50 | +| 21 | medium_click1 | 63 | transition_click_10 | 105 | transition_rampdown_short_sharp2_50 | +| 22 | medium_click2_80 | 64 | transition_hum | 106 | transition_rampup_long_smooth1_50 | +| 23 | medium_click3_60 | 65 | transition_hum_80 | 107 | transition_rampup_long_smooth2_50 | +| 24 | sharp_tick1 | 66 | transition_hum_60 | 108 | transition_rampup_med_smooth1_50 | +| 25 | sharp_tick2_80 | 67 | transition_hum_40 | 109 | transition_rampup_med_smooth2_50 | +| 26 | sharp_tick3_60 | 68 | transition_hum_20 | 110 | transition_rampup_short_smooth1_50 | +| 27 | sh_dblclick_str | 69 | transition_hum_10 | 111 | transition_rampup_short_smooth2_50 | +| 28 | sh_dblclick_str_80 | 70 | transition_rampdown_long_smooth1 | 112 | transition_rampup_long_sharp1_50 | +| 29 | sh_dblclick_str_60 | 71 | transition_rampdown_long_smooth2 | 113 | transition_rampup_long_sharp2_50 | +| 30 | sh_dblclick_str_30 | 72 | transition_rampdown_med_smooth1 | 114 | transition_rampup_med_sharp1_50 | +| 31 | sh_dblclick_med | 73 | transition_rampdown_med_smooth2 | 115 | transition_rampup_med_sharp2_50 | +| 32 | sh_dblclick_med_80 | 74 | transition_rampdown_short_smooth1 | 116 | transition_rampup_short_sharp1_50 | +| 33 | sh_dblclick_med_60 | 75 | transition_rampdown_short_smooth2 | 117 | transition_rampup_short_sharp2_50 | +| 34 | sh_dblsharp_tick | 76 | transition_rampdown_long_sharp1 | 118 | long_buzz_for_programmatic_stopping | +| 35 | sh_dblsharp_tick_80 | 77 | transition_rampdown_long_sharp2 | 119 | smooth_hum1_50 | +| 36 | sh_dblsharp_tick_60 | 78 | transition_rampdown_med_sharp1 | 120 | smooth_hum2_40 | +| 37 | lg_dblclick_str | 79 | transition_rampdown_med_sharp2 | 121 | smooth_hum3_30 | +| 38 | lg_dblclick_str_80 | 80 | transition_rampdown_short_sharp1 | 122 | smooth_hum4_20 | +| 39 | lg_dblclick_str_60 | 81 | transition_rampdown_short_sharp2 | 123 | smooth_hum5_10 | +| 40 | lg_dblclick_str_30 | 82 | transition_rampup_long_smooth1 | | | +| 41 | lg_dblclick_med | 83 | transition_rampup_long_smooth2 | | | +| 42 | lg_dblclick_med_80 | 84 | transition_rampup_med_smooth1 | | | +### オプションの DRV2605L の定義 + +``` +#define DRV_GREETING *sequence name or number* +``` +触覚フィードバッグが有効な場合、キーボード起動時に特定のシーケンスに合わせて振動します。以下の定義を使って選択することができます: + +``` +#define DRV_MODE_DEFAULT *sequence name or number* +``` +これにより HPT_RST がアクティブモードとして設定するシーケンスを設定します。未定義の場合、HPT_RST が押された時にモードが 1 に設定されます。 + +### DRV2605L 連続触覚モード + +このモードは強さを増減するオプションを使って連続触覚フィードバッグを設定します。 diff --git a/ja/feature_hd44780.md b/ja/feature_hd44780.md new file mode 100644 index 00000000000..b4e1ef03ab3 --- /dev/null +++ b/ja/feature_hd44780.md @@ -0,0 +1,62 @@ +# HD44780 LCD ディスプレイ + + + +これは Peter Fleury の LCD ライブラリの統合です。このページは基本について説明します。[詳細なドキュメントについてはこのページをご覧ください](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) + +HD44780 ディスプレイのサポートを有効にするには、キーボードの `rules.mk` の `HD44780_ENABLE` フラグを yes に設定します。 + +## 設定 + +ディスプレイで使用されるピンとディスプレイの行と列の数を、キーボードの `config.h` に設定する必要があります。 + + +HD44780 のラベルが付いたセクションのコメントを外し、必要に応じてパラメータを変更します。 +```` +/* + * HD44780 LCD ディスプレイ設定 + */ + +#define LCD_LINES 2 //< ディスプレイの表示行数 +#define LCD_DISP_LENGTH 16 //< ディスプレイの行ごとの表示文字数 +#define LCD_IO_MODE 1 //< 0: メモリマップモード 1: IO ポートモード +#if LCD_IO_MODE +#define LCD_PORT PORTB //< LCD 行のためのポート +#define LCD_DATA0_PORT LCD_PORT //< 4ビットデータビット 0 のポート +#define LCD_DATA1_PORT LCD_PORT //< 4ビットデータビット 1 のポート +#define LCD_DATA2_PORT LCD_PORT //< 4ビットデータビット 2 のポート +#define LCD_DATA3_PORT LCD_PORT //< 4ビットデータビット 3 のポート +#define LCD_DATA0_PIN 4 //< 4ビットデータビット 0 のピン +#define LCD_DATA1_PIN 5 //< 4ビットデータビット 1 のピン +#define LCD_DATA2_PIN 6 //< 4ビットデータビット 2 のピン +#define LCD_DATA3_PIN 7 //< 4ビットデータビット 3 のピン +#define LCD_RS_PORT LCD_PORT //< RS 線のためのポート +#define LCD_RS_PIN 3 //< RS 線のためのピン +#define LCD_RW_PORT LCD_PORT //< RW 線のためのポート +#define LCD_RW_PIN 2 //< RW 線のためのピン +#define LCD_E_PORT LCD_PORT //< Enable 線のためのポート +#define LCD_E_PIN 1 //< Enable 線のためのピン +#endif +```` + +他のプロパティを設定する必要がある場合は、それらを `quantum/hd44780.h` からコピーし、`config.h` に設定することができます。(訳注)`quantum/hd44780.h` は `drivers/avr/hd44780.h` の間違いではないかと思われます。 + +## 使用法 + +ディスプレイを初期化するには、以下のパラメータのうちの1つを使って `lcd_init()` を呼び出します: +```` +LCD_DISP_OFF : ディスプレイオフ +LCD_DISP_ON : ディスプレイオン、カーソルオフ +LCD_DISP_ON_CURSOR : ディスプレイオン、カーソルオン +LCD_DISP_ON_CURSOR_BLINK : ディスプレイオン、点滅カーソル +```` +これはキーボードの `matrix_init_kb` またはキーマップの `matrix_init_user` で行うのが最適です。 +使用前にディスプレイをクリアすることをお勧めします。 +そのためには、`lcd_clrscr()` を呼びます。 + +ディスプレイに何かを表示するには、最初に `lcd_gotoxy(column, line)` を呼びます。最初の行の先頭に移動するには、`lcd_gotoxy(0, 0)` を呼び出し、その後 `lcd_puts("example string")` を使って文字列を出力します。 + +ディスプレイを制御することができる、より多くのメソッドがあります。[詳細なドキュメントについてはリンクされたページをご覧ください](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) diff --git a/ja/feature_key_lock.md b/ja/feature_key_lock.md new file mode 100644 index 00000000000..b786fbb048b --- /dev/null +++ b/ja/feature_key_lock.md @@ -0,0 +1,27 @@ +# キーロック + + + +特定のキーを長時間押すことが必要になる場合があります。キーロックは次に押すキーを押したままにします。もう一度押すと、リリースされます。 + +いくつかの文を全て大文字で入力する必要があるとしましょう。`KC_LOCK` を押し、次にシフトを押します。これで、シフトは次にタップするまで押していると見なされます。キーロックを Caps Lock と考えることができますが、さらに強力です。 + +## 使用法 + +最初に `rules.mk` で `KEY_LOCK_ENABLE = yes` を設定することでキーロックを有効にします。次に、キーマップでキーを選択し、それをキーコード `KC_LOCK` に割り当てます。 + +## キーコード + +| キーコード | 説明 | +|---------|--------------------------------------------------------------| +| `KC_LOCK` | キーが再び押されるまで次のキーを押したままにします。 | + +## 注意事項 + +キーロックは、標準アクションキーと[ワンショットモディファイア](ja/one_shot_keys.md)キー (例えば、Shift を `OSM(KC_LSFT)` と定義した場合)のみを押し続けることができます。 +これは、QMK の特殊機能(ワンショットモディファイアを除く)、または `KC_LPRN` のような shift を押されたキーのバージョンは含みません。[基本的なキーコード](ja/keycodes_basic.md)リストにある場合、押したままにすることができます。 + +レイヤーの切り替えは、キーロックを解除しません。 diff --git a/ja/feature_layers.md b/ja/feature_layers.md new file mode 100644 index 00000000000..d27251f7e3b --- /dev/null +++ b/ja/feature_layers.md @@ -0,0 +1,99 @@ +# レイヤー :id=layers + + + +QMK ファームウェアの最も強力で良く使われている機能の一つは、レイヤーを使う機能です。ほとんどの人にとって、これはラップトップやタブレットキーボードにあるのと同じように、様々なキーを可能にするファンクションキーに相当します。 + +レイヤースタックがどのように動作するかの詳細な説明については、[キーマップの概要](ja/keymap.md#keymap-and-layers)を調べてください。 + +## レイヤーの切り替えとトグル :id=switching-and-toggling-layers + +以下の関数により、様々な方法でレイヤーをアクティブにすることができます。レイヤーは通常、独立したレイアウトでは無いことに注意してください -- 複数のレイヤーを一度にアクティブにすることができ、レイヤーが `KC_TRNS` を使ってキーの押下を下のレイヤーへと透過させることが一般的です。MO()、LM()、TT() あるいは LT() を使って一時的なレイヤーの切り替えを使う場合、上のレイヤーのキーを透過にするようにしてください。さもないと意図したように動作しないかもしれません。 + +* `DF(layer)` - デフォルトレイヤーを切り替えます。デフォルトレイヤーは、他のレイヤーがその上に積み重なっている、常にアクティブな基本レイヤーです。デフォルトレイヤーの詳細については以下を見てください。これは QWERTY から Dvorak レイアウトに切り替えるために使うことができます。(これは一時的な切り替えであり、キーボードの電源が切れるまでしか持続しないことに注意してください。デフォルトレイヤーを永続的に変更するには、[process_record_user](ja/custom_quantum_functions.md#programming-the-behavior-of-any-keycode) 内で `set_single_persistent_default_layer` 関数を呼び出すなど、より深いカスタマイズが必要です。) +* `MO(layer)` - 一時的に*レイヤー*をアクティブにします。キーを放すとすぐに、レイヤーは非アクティブになります。 +* `LM(layer, mod)` - (`MO` のように)一時的に*レイヤー*をアクティブにしますが、モディファイア *mod* がアクティブな状態です。layer 0-15 と、左モディファイアのみをサポートします: `MOD_LCTL`、`MOD_LSFT`、`MOD_LALT`、`MOD_LGUI` (`KC_` 定数の代わりに `MOD_` 定数を使うことに注意してください)。これらのモディファイアは、例えば `LM(_RAISE, MOD_LCTL | MOD_LALT)` のように、ビット単位の OR を使って組み合わせることができます。 +* `LT(layer, kc)` - ホールドされた時に*レイヤー*を一時的にアクティブにし、タップされた時に *kc* を送信します。layer 0-15 のみをサポートします。 +* `OSL(layer)` - 次のキーが押されるまで、一時的に*レイヤー*をアクティブにします。詳細と追加機能については、[ワンショットキー](ja/one_shot_keys.md)を見てください。 +* `TG(layer)` - *レイヤー*を切り替えます。非アクティブな場合はアクティブにし、逆も同様です。 +* `TO(layer)` - *レイヤー*をアクティブにし、他の全てのレイヤー(デフォルトレイヤーを除く)を非アクティブにします。この関数は特別です。1つのレイヤーをアクティブなレイヤースタックに追加/削除する代わりに、現在のアクティブなレイヤーを完全に置き換え、唯一上位のレイヤーを下位のレイヤーで置き換えることができるからです。これはキーダウンで(キーが押されるとすぐに)アクティブになります。 +* `TT(layer)` - レイヤーのタップ切り替え。キーを押したままにすると*レイヤー*がアクティブにされ、放すと非アクティブになります (`MO` 風)。繰り返しタップすると、レイヤーはオンあるいはオフを切り替えます (`TG` 風)。デフォルトでは5回のタップが必要ですが、`TAPPING_TOGGLE` を定義することで変更することができます -- 例えば、2回のタップだけで切り替えるには、`#define TAPPING_TOGGLE 2` を定義します。 + +### 注意事項 :id=caveats + +現在のところ、`LT()` と `MT()` は[基本的なキーコードセット](ja/keycodes_basic.md)に制限されています。つまり、`LCTL()`、`KC_TILD` あるいは `0xFF` より大きなキーコードを使うことができません。特に、`LT` と `MT` のような二重の機能キーは16ビットキーコードを使います。4ビットは機能の識別のために使われ、次の12ビットはパラメータに分かれます。レイヤータップはレイヤーに4ビットを使います(実はレイヤータップがレイヤー 0-15 に制限されている理由です)。モッドタップも同じですが、識別子に4ビット、モッドのために4ビットが使われ、全体でキーコードに8ビットを使います。このため、使用されるキーコードは `0xFF` (0-255) に制限され、基本的なキーコードのみです。 + +これを拡張してもせいぜい複雑になるだけでしょう。32ビットキーコードに移行すると、これの多くが解決されますが、キーマップマトリックスが使用する領域が2倍になります。また、問題が起きる可能性もあります。タップしたキーコードにモディファイアを適用する必要がある場合は、[タップダンス](ja/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys)を使うことができます。 + +さらに、モッドタップあるいはレイヤータップで少なくとも1つの右手用のモディファイアが指定された場合、指定された全てのモディファイアが右手用になるため、2つをうまく組み合わせて一致させることはできません。 + +## レイヤーとの連携 :id=working-with-layers + +レイヤーを切り替える時は注意してください。(キーボードを取り外さずに)そのレイヤーを非アクティブにすることができずレイヤーから移動できなくなる可能性があります。最も一般的な問題を避けるためのガイドラインを作成しました。 + +### 初心者 :id=beginners + +QMK を使い始めたばかりの場合は、全てを単純にしたいでしょう。レイヤーをセットアップする時は、これらのガイドラインに従ってください: + +* デフォルトの "base" レイヤーとして、layer 0 をセットアップします。これは通常の入力レイヤーであり、任意のレイアウト (qwerty、dvorak、colemak など)にすることができます。通常はキーボードのキーのほとんどまたは全てが定義されているため、これを最下位のレイヤーとして設定することが重要です。そうすることで、もしそれが他のレイヤーの上 (つまりレイヤー番号が大きい)にある場合の影響を防ぎます。 +* layer 0 をルートとして、レイヤーを "ツリー" レイアウトに配置します。他の複数のレイヤーから同じレイヤーに行こうとしないでください。 +* 各レイヤーのキーマップでは、より高い番号のレイヤーのみを参照します。レイヤーは最大の番号(最上位)のアクティブレイヤーから処理されるため、下位レイヤーの状態を変更するのは難しくエラーが発生しやすくなります。 + +### 中級ユーザ :id=intermediate-users + +複数の基本レイヤーが必要な場合があります。例えば、QWERTY と Dvorak を切り替える場合、国ごとに異なるレイアウトを切り替える場合、あるいは異なるビデオゲームごとにレイアウトを切り替える場合などです。基本レイヤーは常に最小の番号のレイヤーである必要があります。複数の基本レイヤーがある場合、常にそれらを相互排他的に扱う必要があります。1つの基本レイヤーがオンの場合、他をオフにします。 + +### 上級ユーザ :id=advanced-users + +レイヤーがどのように動作し、何ができるかを理解したら、より創造的になります。初心者のセクションで列挙されている規則は、幾つかの巧妙な詳細を回避するのに役立ちますが、特に超コンパクトなキーボードのユーザにとって制約になる場合があります。レイヤーの仕組みを理解することで、レイヤーをより高度な方法で使うことができます。 + +レイヤーは番号順に上に積み重なっています。キーの押下の動作を決定する時に、QMK は上から順にレイヤーを走査し、`KC_TRNS` に設定されていない最初のアクティブなレイヤーに到達すると停止します。結果として、現在のレイヤーよりも数値的に低いレイヤーをアクティブにし、現在のレイヤー(あるいはアクティブでターゲットレイヤーよりも高い別のレイヤー)に `KC_TRNS` 以外のものがある場合、それが送信されるキーであり、アクティブ化したばかりのレイヤー上のキーではありません。これが、ほとんどの人の "なぜレイヤーが切り替わらないのか" 問題の原因です。 + +場合によっては、マクロ内あるいはタップダンスルーチンの一部としてレイヤーを切り替えほうが良いかもしれません。`layer_on` はレイヤーをアクティブにし、`layer_off` はそれを非アクティブにします。もっと多くのレイヤーに関する関数は、[action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_layer.h) で見つけることができます。 + +## 関数 :id=functions + +レイヤーの使用あるいは操作に関係する多くの関数(と変数)があります。 + +| 関数 | 説明 | +| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `layer_state_set(layer_mask)` | 直接レイヤーの状態を設定する (推奨。何をしているのか分かっていない場合は使わないでください)。 | +| `layer_clear()` | 全てのレイヤーを消去する (全てをオフにします)。 | +| `layer_move(layer)` | 指定されたレイヤーをオンにし、それ以外をオフにする。 | +| `layer_on(layer)` | 指定されたレイヤーをオンにし、それ以外を既存の状態のままにする。 | +| `layer_off(layer)` | 指定されたレイヤーをオフにし、それ以外を既存の状態のままにする。 | +| `layer_invert(layer)` | 指定されたレイヤーの状態を反転/トグルする。 | +| `layer_or(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で一致するビットに基づいてレイヤーをオンにする。 | +| `layer_and(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で有効なビットに基づいてレイヤーをオンにする。 | +| `layer_xor(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で一致しないビットに基づいてレイヤーをオンにする。 | +| `layer_debug(layer_mask)` | デバッガのコンソールに現在のビットマスクと最も高いレイヤーを出力する。 | +| `default_layer_set(layer_mask)` | 直接デフォルトレイヤーの状態を設定する (推奨。何をしているのか分かっていない場合は使わないでください)。 | +| `default_layer_or(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致するビットに基づいてレイヤーをオンにする。 | +| `default_layer_and(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致する有効なビットに基づいてレイヤーをオンにする。 | +| `default_layer_xor(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致しないビットに基づいてレイヤーをオンにする。 | +| `default_layer_debug(layer_mask)` | デバッガのコンソールに現在のビットマスクと最も高いアクティブなレイヤーを出力する。 | +| [`set_single_persistent_default_layer(layer)`](ja/ref_functions.md#setting-the-persistent-default-layer) | デフォルトレイヤーを設定し、それを永続化メモリ (EEPROM) に書き込む。 | +| [`update_tri_layer(x, y, z)`](ja/ref_functions.md#update_tri_layerx-y-z) | レイヤー `x` と `y` の両方がオンであるかを調べ、それに基づいて `z` を設定する(両方がオンの場合オン、そうでなければオフ)。 | +| [`update_tri_layer_state(state, x, y, z)`](ja/ref_functions.md#update_tri_layer_statestate-x-y-z) | `update_tri_layer(x, y, z)` と同じことをするが、`layer_state_set_*` 関数から呼ばれる。 | + + +呼び出すことができる関数に加えて、レイヤーが変更されるたびに呼び出されるコールバック関数が幾つかあります。これはレイヤー状態を関数に渡し、読み取りや変更することができます。 + +| コールバック | 説明 | +| --------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| `layer_state_set_kb(layer_state_t state)` | キーボードレベルのレイヤー関数のためのコールバック。 | +| `layer_state_set_user(layer_state_t state)` | ユーザレベルのレイヤー関数のためのコールバック。 | +| `default_layer_state_set_kb(layer_state_t state)` | キーボードレベルのデフォルトレイヤー関数のためのコールバック。キーボードの初期化時に呼ばれます。 | +| `default_layer_state_set_user(layer_state_t state)` | ユーザレベルのデフォルトレイヤー関数のためのコールバック。キーボードの初期化時に呼ばれます。 | + +?> これらのコールバックを使うための追加の情報については、[レイヤー変換コード](ja/custom_quantum_functions.md#layer-change-code)のドキュメントを調べてください。 + +次の関数やマクロを使って、特定のレイヤーの状態を確認することもできます。 + +| 関数 | 説明 | 別名 | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | +| `layer_state_is(layer)` | 指定された `layer` がグローバルに有効かどうかを確認する。 | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` | +| `layer_state_cmp(state, layer)` | `state` を確認して指定された `layer` が有効かどうかを確認する。レイヤーのコールバックで使うことを目的とする。 | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` | diff --git a/ja/feature_layouts.md b/ja/feature_layouts.md new file mode 100644 index 00000000000..9b36a1eda56 --- /dev/null +++ b/ja/feature_layouts.md @@ -0,0 +1,114 @@ +# レイアウト: 複数のキーボードで1つのキーマップを使用 + + + +`layouts/` フォルダは、様々なキーボードに適用できる色々な物理キーレイアウトを含みます。 + +``` +layouts/ ++ default/ +| + 60_ansi/ +| | + readme.md +| | + layout.json +| | + a_good_keymap/ +| | | + keymap.c +| | | + readme.md +| | | + config.h +| | | + rules.mk +| | + / +| | + ... +| + / ++ community/ +| + / +| + ... +``` + +`layouts/default/` と `layouts/community/` は、レイアウト「repositories」の2つの例です。現在のところ、`default` にはユーザの参考用に、レイアウトに関する全ての情報および、`default_` という名前の1つのデフォルトのキーマップが含まれています。`community` には全ての共有キーマップが含まれており、それらはユーザが `layouts/` にクローンするための別のリポジトリに分割することを最終的な目的としていますQMK は `layouts/` 内のすべてのフォルダを検索するため、ここに複数のリポジトリを持つことができます。 + +各レイアウトフォルダは、レイアウトの物理的な側面に基づいて、可能な限り一般的な名称で(`[a-z0-9_]`)という名前が付けられ、キーボードで定義されるレイアウトと一緒に `readme.md` を含みます。 + +```md +# 60_ansi + + LAYOUT_60_ansi +``` + +新しい名前は既存のレイアウトで設定された標準に準拠しようと努力する必要があり、必要に応じて PR/Issue で議論することができます。 + +## レイアウトのサポート + +キーボードがレイアウトをサポートするために、変数は `.h` で定義し、引数/キー (できれば物理レイアウト)の数に一致している必要があります。 + + #define LAYOUT_60_ansi KEYMAP_ANSI + +レイアウトの名前は次の正規表現に一致しなければなりません: `[a-z0-9_]+` + +フォルダ名はキーボードの `rules.mk` に追加する必要があります: + + LAYOUTS = 60_ansi + +`LAYOUTS` は任意のキーボードフォルダレべルの `rules.mk` に設定することができます: + + LAYOUTS = 60_iso + +ただし、`LAYOUT_` 変数は `.h` でも定義する必要があります。 + +## キーマップのビルド + +以下の形式でコマンドを使ってキーボードキーマップを作成できるはずです: + + make : + +### レイアウトの競合 +キーボードが複数のレイアウトオプションをサポートし、 + + LAYOUTS = ortho_4x4 ortho_4x12 + +なおかつ両方のオプションについてレイアウトが存在する場合、 +``` +layouts/ ++ community/ +| + ortho_4x4/ +| | + / +| | | + ... +| + ortho_4x12/ +| | + / +| | | + ... +| + ... +``` + +FORCE_LAYOUT 引数はどのレイアウトをビルドするかを指定するために使うことができます + + make : FORCE_LAYOUT=ortho_4x4 + make : FORCE_LAYOUT=ortho_4x12 + +## キーボードに依存しないレイアウトを作成するためのヒント + +### インクルード + +`#include "planck.h"` を使う代わりに、以下の行を使ってコンパイルされる `.h` (`.h` はここでインクルードすべきではありません)ファイルをインクルードすることができます: + + #include QMK_KEYBOARD_H + +キーボード固有のコードを保持したい場合は、これらの変数を使って `#ifdef` 文でエスケープすることができます: + +* `KEYBOARD__` + +例えば: + +```c +#ifdef KEYBOARD_planck + #ifdef KEYBOARD_planck_rev4 + planck_rev4_function(); + #endif +#endif +``` + +名前は小文字でキーボード/リビジョンのフォルダ/ファイル名と正確に一致することに注意してください。 + +### キーマップ + +同じレイアウトで分割および非分割キーボードをサポートするためには、キーマップでキーボード非依存の `LAYOUT_` マクロを使う必要があります。例えば、Let's Split および Planck が同じレイアウトを共有するには、`LAYOUT_planck_grid` や C 配列の場合の単なる `{}` の代わりに、`LAYOUT_ortho_4x12` を使う必要があります。 diff --git a/ja/feature_leader_key.md b/ja/feature_leader_key.md new file mode 100644 index 00000000000..61d6f5a8e05 --- /dev/null +++ b/ja/feature_leader_key.md @@ -0,0 +1,151 @@ +# リーダーキー: 新しい種類のモディファイア + + + +もしあなたが Vim を使ったことがある場合、リーダーキーは何であるかを知っています。そうでなければ、素晴らしい概念を発見しようとしています。:) 例えば、Alt+Shift+W を押す(3つのキーを同時に押す)代わりに、キーの_シーケンス_を押すことができたらどうでしょう?つまり、特別なモディファイア (リーダーキー)を押して、続けて W と C を押すと (単純にキーを高速に繋げます)、何かが起こります。 + +それが `KC_LEAD` の機能です。以下は例です: + +1. リーダーキーとして使いたいキーボードのキーを選択します。それにキーコード `KC_LEAD` を割り当てます。このキーはこのためだけの専用です -- 単一アクションのキーで、他の用途には使うことができません。 +2. `config.h` に `#define LEADER_TIMEOUT 300` という行を追加します。これによって `KC_LEAD` キーのタイムアウトを設定します。具体的には、`KC_LEAD` キーを押してからリーダーキーのシーケンスを完了するまで一定の時間しかありません。ここでの `300` はそれを300msに設定します。この値を増やして、シーケンスを入力する時間を増やすことができます。ただし、この時間中に押されたキーは全て途中で遮られ、送信されません。そのためこの値は小さくしておいたほうが良いかもしれません。 + * デフォルトでは、このタイムアウトは、`KC_LEAD` を押してからシーケンス全体が完了するまでに掛かる時間です。これは一部の人にとっては非常に短いかもしれません。そのため、このタイムアウトを増やしたほうが良い場合もあります。必要に応じて、`LEADER_PER_KEY_TIMING` オプションを有効にしたほうが良い場合もあります。これは各キーがタップされる度にタイムアウトまでの時間をリセットする機能です。これにより、タイムアウト時間を短くしつつも、比較的長いシーケンスを使うことができます。このオプションを有効にするには、`config.h` に `#define LEADER_PER_KEY_TIMING` を追加します。 +3. `matrix_scan_user` 関数の中で、以下のようなものを追加します: + +```c +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + leading = false; + leader_end(); + + SEQ_ONE_KEY(KC_F) { + // マクロ内でできること + SEND_STRING("QMK is awesome."); + } + SEQ_TWO_KEYS(KC_D, KC_D) { + SEND_STRING(SS_LCTL("a") SS_LCTL("c")); + } + SEQ_THREE_KEYS(KC_D, KC_D, KC_S) { + SEND_STRING("https://start.duckduckgo.com\n"); + } + SEQ_TWO_KEYS(KC_A, KC_S) { + register_code(KC_LGUI); + register_code(KC_S); + unregister_code(KC_S); + unregister_code(KC_LGUI); + } + } +} +``` + +ご覧のとおり、幾つかの関数があります。`SEQ_ONE_KEY` を単一キーシーケンス (リーダーの後に1つのキーのみ)に使い、より長いシーケンスについては `SEQ_TWO_KEYS`、`SEQ_THREE_KEYS` から `SEQ_FIVE_KEYS` を使うことができます。 + +これらはそれぞれ1つ以上のキーコードを引数として受け付けます。これは重要な点です: **キーボードの任意のレイヤー**のキーコードを使うことができます。当たり前ですが、リーダーマクロが発動するにはそのレイヤーがアクティブである必要があります + +## `rules.mk` にリーダーキーサポートを追加 + +リーダーキーのサポートを追加するには、単純にキーマップの `rules.mk` に1行を追加します: + +```make +LEADER_ENABLE = yes +``` + +## リーダーキーのキーごとのタイミング + +長いリーダーキー文字列のためや 200wpm のタイピングスキルが無い場合に、非常に長いタイムアウト時間に頼るのではなく、キーを押すごとに入力を完了するまでの時間を増やす機能を使用することができます。これは、リーダーキーを使ってタップダンスを再現する場合に非常に役立ちます (C, C, C のような同じキーを複数回タップする場合)。 + +これを有効にするには、以下を `config.h` に配置します: +```c +#define LEADER_PER_KEY_TIMING +``` + +この後、`LEADER_TIMEOUT` を 300ms 未満に下げることをお勧めします。 + +```c +#define LEADER_TIMEOUT 250 +``` + +これで、リーダーキーのタイムアウト時間を 1000ms に設定することなく以下のようなことが可能になると思われます。 + +```c +SEQ_THREE_KEYS(KC_C, KC_C, KC_C) { + SEND_STRING("Per key timing is great!!!"); +} +``` + +## 厳密なキー処理 + +デフォルトでは、リーダーキー機能は、リーダーシーケンスの確認時に [`モッドタップ`](ja/mod_tap.md) および [`レイヤータップ`](ja/feature_layers.md#switching-and-toggling-layers) 機能からのキーコードをフィルターします。つまり、`LT(3, KC_A)` を使っている場合、`LT(3, KC_A)` ではなくシーケンスの `KC_A` として取り出され、新しいユーザにとってより期待される動作を提供します。 + +ほとんどの場合これで問題ありませんが、シーケンスでキーコード全体(例えば、上の例での `LT(3, KC_A)`) を指定したい場合は、`config.h` ファイルに `#define LEADER_KEY_STRICT_KEY_PROCESSING` を追加することこのような機能を有効にすることができます。これでフィルタリングが無効になり、キーコード全体を指定する必要があります。 + +## カスタマイズ + +リーダーキー機能には、リーダーキー機能の動作にいくらかのカスタマイズを追加する方法があります。リーダーキー機能のプロセスの特定の部分で呼び出すことができる2つの関数、`leader_start()` と `leader_end()` です。 + +`KC_LEAD` キーがタップされた時に `leader_start()` 関数が呼ばれ、リーダーシーケンスが完了するか、リーダータイムアウトの時間に達した時に `leader_end()` 関数が呼ばれます。 + +リーダーシーケンスにフィードバック(ビープまたは音楽を再生するなど)を追加するために、これらの関数をコード (通常 は`keymap.c`)に追加することができます。 + +```c +void leader_start(void) { + // シーケンスの開始 +} + +void leader_end(void) { + // シーケンスの終了 (成功しない/失敗を検知) +} +``` + +### 例 + +この例では、リーダーシーケンスを開始するために `KC_LEAD` を押すとマリオの "One Up" 音が再生され、正常に完了した場合は "All Star" が再生され、失敗した場合は "Rick Roll" を再生されます。 + +```c +bool did_leader_succeed; +#ifdef AUDIO_ENABLE +float leader_start[][2] = SONG(ONE_UP_SOUND ); +float leader_succeed[][2] = SONG(ALL_STAR); +float leader_fail[][2] = SONG(RICK_ROLL); +#endif +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + did_leader_succeed = leading = false; + + SEQ_ONE_KEY(KC_E) { + // マクロ内でできること + SEND_STRING(SS_LCTL(SS_LSFT("t"))); + did_leader_succeed = true; + } else + SEQ_TWO_KEYS(KC_E, KC_D) { + SEND_STRING(SS_LGUI("r") "cmd\n" SS_LCTL("c")); + did_leader_succeed = true; + } + leader_end(); + } +} + +void leader_start(void) { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_start); +#endif +} + +void leader_end(void) { + if (did_leader_succeed) { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_succeed); +#endif + } else { +#ifdef AUDIO_ENABLE + PLAY_SONG(leader_fail); +#endif + } +} +``` diff --git a/ja/feature_led_matrix.md b/ja/feature_led_matrix.md new file mode 100644 index 00000000000..b2595f9989e --- /dev/null +++ b/ja/feature_led_matrix.md @@ -0,0 +1,95 @@ +# LED マトリックスライト + + + +この機能により、外部ドライバによって駆動される LED マトリックスを使うことができます。この機能は、バックライト制御と同じキーコードを使えるようにするため、バックライトシステムに接続します。 + +RGB LED を使いたい場合は、代わりに [RGB マトリックスサブシステム](ja/feature_rgb_matrix.md) を使うべきです。 + +## ドライバ設定 + +### IS31FL3731 + +I2C IS31FL3731 RGB コントローラを使ったアドレス指定可能な LED マトリックスライトのための基本的なサポートがあります:有効にするには、`rules.mk` に以下を追加します: + + LED_MATRIX_ENABLE = IS31FL3731 + +1から4個の IS31FL3731 IC を使うことができます。キーボード上に存在しない IC の `LED_DRIVER_ADDR_` 定義を指定しないでください。`config.h` に以下の項目を定義することができます: + +| 変数 | 説明 | デフォルト | +|----------|-------------|---------| +| `ISSI_TIMEOUT` | (オプション) i2c メッセージを待つ時間 | 100 | +| `ISSI_PERSISTENCE` | (オプション) 失敗したメッセージをこの回数再試行する | 0 | +| `LED_DRIVER_COUNT` | (必須) LED ドライバ IC の数 | | +| `LED_DRIVER_LED_COUNT` | (必須) 全てのドライバの LED ライトの数 | | +| `LED_DRIVER_ADDR_1` | (必須) 最初の LED ドライバのアドレス | | +| `LED_DRIVER_ADDR_2` | (オプション) 2番目の LED ドライバのアドレス | | +| `LED_DRIVER_ADDR_3` | (オプション) 3番目の LED ドライバのアドレス | | +| `LED_DRIVER_ADDR_4` | (オプション) 4番目の LED ドライバのアドレス | | + +2つのドライバを使う例です。 + + // これは7ビットのアドレスで、左シフトされます + // ビット0に0を設定すると書き込み、1を設定すると読み込みです (I2C プロトコルに従う) + // アドレスは配線によって変わります: + // 0b1110100 AD <-> GND + // 0b1110111 AD <-> VCC + // 0b1110101 AD <-> SCL + // 0b1110110 AD <-> SDA + #define LED_DRIVER_ADDR_1 0b1110100 + #define LED_DRIVER_ADDR_2 0b1110110 + + #define LED_DRIVER_COUNT 2 + #define LED_DRIVER_1_LED_COUNT 25 + #define LED_DRIVER_2_LED_COUNT 24 + #define LED_DRIVER_LED_COUNT LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL + +現在、2つのドライバのみがサポートされますが、4つの組み合わせ全てをサポートすることは簡単です。 + +`.c` に全ての LED を列挙する配列を定義します: + + const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + /* これらの位置については IS31 マニュアルを参照してください + * driver + * | LED address + * | | */ + {0, C3_3}, + .... + } + +ここで、`Cx_y` は[データシート](http://www.issi.com/WW/pdf/31FL3731.pdf)およびヘッダファイル `drivers/issi/is31fl3731-simple.h` で定義されるマトリックス内の LED の位置です。`driver` は `config.h` で定義したドライバのインデックス(`0`、`1`、`2`、`3`のいずれか)です。 + +## キーコード + +現在のところ、全ての LED マトリックスのキーコードは[バックライトシステム](ja/feature_backlight.md)と共有されます。 + +## LED マトリックス効果 + +現在のところ、LED マトリックス効果は作成されていません。 + +## カスタムレイヤー効果 + +カスタムレイヤー効果は `.c` 内で以下を定義することで行うことができます: + + void led_matrix_indicators_kb(void) { + led_matrix_set_index_value(index, value); + } + +同様の関数がキーマップ内で `led_matrix_indicators_user` として動作します。 + +## サスペンド状態 + +サスペンド機能を使うには、以下を `.c` に追加します: + + void suspend_power_down_kb(void) + { + led_matrix_set_suspend_state(true); + } + + void suspend_wakeup_init_kb(void) + { + led_matrix_set_suspend_state(false); + } diff --git a/ja/feature_macros.md b/ja/feature_macros.md new file mode 100644 index 00000000000..5fbe36726ad --- /dev/null +++ b/ja/feature_macros.md @@ -0,0 +1,402 @@ +# マクロ + + + +マクロにより、1つのキーを押すだけで複数のキーストロークを送信することができます。QMK にはマクロを定義し使う方法が幾つかあります。これらはなんでもすることができます: よく使うフレーズの入力、コピーペースト、反復的なゲームの動き、あるいはコードを書くことさえ手助けします。 + +!> **セキュリティの注意**: マクロを使って、パスワード、クレジットカード番号、その他の機密情報のいずれも送信することが可能ですが、それは非常に悪い考えです。あなたのキーボードを手に入れた人は誰でもテキストエディタを開いてその情報にアクセスすることができます。 + +## 新しい方法: `SEND_STRING()` と `process_record_user` + +単語またはフレーズを入力するキーが欲しい時があります。最も一般的な状況のために `SEND_STRING()` を提供しています。これは文字列(つまり、文字のシーケンス)を入力します。簡単にキーコードに変換することができる全ての ASCII 文字がサポートされています (例えば、`qmk 123\n\t`)。 + +以下は2キーのキーボードのための `keymap.c` の例です: + +```c +enum custom_keycodes { + QMKBEST = SAFE_RANGE, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QMKBEST: + if (record->event.pressed) { + // キーコード QMKBEST が押された時 + SEND_STRING("QMK is the best thing ever!"); + } else { + // キーコード QMKBEST が放された時 + } + break; + } + return true; +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = { + {QMKBEST, KC_ESC}, + // ... + }, +}; +``` + +ここで起きることは以下の通りです: +最初に他のキーコードで使用されていない範囲で新しいカスタムキーコードを定義します。 +次に、`process_record_user` 関数を使います。これはキーが押されるか放されるたびに呼び出され、カスタムキーコードがアクティブかどうかを確認します。 +アクティブな場合、`SEND_STRING` マクロ (これは C プロセッサのマクロで、QMK のマクロと混同しないでください)を介して文字列 `"QMK is the best thing ever!"` をコンピュータに送信します。 +呼び出し元に、処理したばかりのキー押下を通常通り(機能を置き換えたり変更したりしなかったので)処理し続けるよう指示するため、`true` を返します。 +最後に、最初のボタンがマクロをアクティブにし、2番目のボタンが単なるエスケープボタンになるようにキーマップを定義します。 + +複数のマクロを追加することもできます。 +以下のように、別のキーコードを追加し、switch 文に別の case ラベルを追加することで、それを行うことができます: + +```c +enum custom_keycodes { + QMKBEST = SAFE_RANGE, + QMKURL, + MY_OTHER_MACRO, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QMKBEST: + if (record->event.pressed) { + // キーコード QMKBEST が押された時 + SEND_STRING("QMK is the best thing ever!"); + } else { + // キーコード QMKBEST が放された時 + } + break; + + case QMKURL: + if (record->event.pressed) { + // キーコード QMKURL が押された場合 + SEND_STRING("https://qmk.fm/\n"); + } else { + // キーコード QMKURL が放された場合 + } + break; + + case MY_OTHER_MACRO: + if (record->event.pressed) { + SEND_STRING(SS_LCTL("ac")); // 全てを選択しコピーします + } + break; + } + return true; +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = { + {MY_CUSTOM_MACRO, MY_OTHER_MACRO}, + // ... + }, +}; +``` + +### 高度なマクロ + +`process_record_user()` 関数のほかに、`post_process_record_user()` 関数があります。これは `process_record` の後に実行され、キーストロークが送信された後の処理に使用できます。これは例えば、通常のキーの前に押され、通常のキーの後で放されるキーがほしい場合に便利です。 + +この例では、通常のキー入力を変更して、キーストロークが通常送信される前に `F22` が押されるようにし、キーが放された__後にのみ__ `F22` キーを放します。 + +```c +static uint8_t f22_tracker; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_A ... KC_F21: // F22 をスキップする方法に注意してください + case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです + if (record->event.pressed) { + register_code(KC_F22); //これは F22 を押したことを送信することを意味します + f22_tracker++; + register_code(keycode); + return false; + } + break; + } + return true; +} + +void post_process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_A ... KC_F21: // F22 をスキップする方法に注意してください + case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです + if (!record->event.pressed) { + f22_tracker--; + if (!f22_tracker) { + unregister_code(KC_F22); //これは F22 を放したことを送信することを意味します + } + } + break; + } +} +``` + + +### タップ、ダウン、アップ + +`Ctrl` あるいは `Home` など、ソースコードに文字列として表記できないキーをマクロで使うこともできます。 +以下のようにラップすることで任意のコードを送信することができます: + +* `SS_TAP()` キーを押して放します。 +* `SS_DOWN()` キーを押します (ただし、放しません)。 +* `SS_UP()` キーを放します。 + +例えば: + + SEND_STRING(SS_TAP(X_HOME)); + +`KC_HOME` をタップします - プリフィックスが `X_` で `KC_` ではないことに注意してください。以下のように、他の文字列と組み合わせることもできます: + + SEND_STRING("VE"SS_TAP(X_HOME)"LO"); + +これは "VE" に続けて `KC_HOME` をタップ、そして "LO" (新しい行の場合は "LOVE" と綴る)を送信します。 + +文字列に遅延を追加することもできます: + +* `SS_DELAY(msecs)` は指定されたミリ秒だけ遅らせます。 + +例えば: + + SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO"); + +これは "VE" 、1秒の遅延、`KC_HOME` をタップ、"LO" (新しい行の場合は "LOVE" と綴るが、中間に遅延がある) を送信します。 + +使用できるモッドショートカットもいくつかあります: + +* `SS_LCTL(文字列)` +* `SS_LSFT(文字列)` +* `SS_LALT(文字列)`、`SS_LOPT(文字列)` +* `SS_LGUI(文字列)`、`SS_LCMD(文字列)`、`SS_LWIN(文字列)` +* `SS_RCTL(文字列)` +* `SS_RSFT(文字列)` +* `SS_RALT(文字列)`、`SS_ROPT(文字列)`、`SS_ALGR(文字列)` +* `SS_RGUI(文字列)`、`SS_RCMD(文字列)`、`SS_RWIN(文字列)` + +これらはそれぞれの修飾キーを押し、指定された文字列を送信してから、修飾キーを解放します。 +それらは以下のように使うことができます: + + SEND_STRING(SS_LCTL("a")); + +これは、左 Control +`a` (左 Control をダウンし、`a`、左 Control をアップ)を送信します - それらは文字列(例えば `"k"`)であり、`X_K` キーコードでは無いことに注意してください。 + +### 代替キーマップ + +デフォルトでは、QWERTY レイアウトの US キーマップを想定しています; それを変更したい場合(例えば OS がソフトウェア Colemak を使う場合)、キーマップのどこかに以下を含めます: + + #include + +### メモリ内の文字列 + +何らかの理由で文字列を操作していて、(リテラル、文字列定数の代わりに)生成したばかりのものを出力する必要がある場合は、以下のように `send_string()` を使うことができます: + +```c +char my_str[4] = "ok."; +send_string(my_str); +``` + +上で定義したショートカットは `send_string()` では動作しないですが、必要に応じて別の行に分けることができます: + +```c +char my_str[4] = "ok."; +SEND_STRING("I said: "); +send_string(my_str); +SEND_STRING(".."SS_TAP(X_END)); +``` + + +## 高度なマクロ関数 + +マクロの生成に役立つ関数が幾つかあります。マクロの中にかなり高度なコードを書くことができますが、機能が複雑になりすぎる場合は、代わりにカスタムキーコードを定義することをお勧めします。マクロはシンプルにしなければなりません。 + +?> 追加の機能として、[便利な関数](ja/ref_functions.md) の中で説明される関数を使うこともできます。例えば `reset_keyboard()` によりマクロの一部としてキーボードをリセットすることができます。 + +### `record->event.pressed` + +これでスイッチが押されているか放されているかどうかをテストすることができます。以下が例です。 + +```c + if (record->event.pressed) { + // キーダウン時 + } else { + // キーアップ時 + } +``` + +### `register_code();` + +これはコンピュータに `` キーダウンイベントを送信します。例として `KC_ESC`、`KC_C`、`KC_4` や、`KC_LSFT` と `KC_LGUI` のような修飾キーなどもあります。 + +### `unregister_code();` + +`register_code` 関数と対応して、これは `` キーアップイベントをコンピュータに送信します。これを使わない場合、キーは送信されるまで押し続けられます。 + +### `tap_code();` + +これは `register_code()` を送信し、その後 `unregister_code()` を送信します。押下とリリースイベントの両方を送信する場合に便利です (押し続けるのではなく、キーを"タップ"する)。 + +タップの登録(解除)に問題がある場合、`config.h` ファイルで `#define TAP_CODE_DELAY 100` を設定することで、登録イベントと解除イベントの間に遅延を追加することができます。値はミリ秒です。 + +### `register_code16();`、`unregister_code16();`、`tap_code16();` + +これらの関数は対応する通常の関数と同様に機能しますが、修飾キーで修飾されたキーコードを使うことができます (Shift、Alt、Control、GUI を適用)。 + +例えば、修飾キーを押して(`register_code()`して)、キーコードを押す(`register_code()`する)代わりに、`register_code16(S(KC_5));` を使うことができます。 + +### `clear_keyboard();` + +これは現在押されている全ての修飾キーとキーをクリアします。 + +### `clear_mods();` + +これは現在押されている全ての修飾キーをクリアします。 + +### `clear_keyboard_but_mods();` + +これは現在押されている修飾キー以外の全てのキーをクリアします。 + +## 高度な例: + +### スーパー ALT↯TAB + +このマクロは `KC_LALT` を登録し、`KC_TAB` をタップして、1000ms 待ちます。キーが再度タップされると、別の `KC_TAB` が送信されます; タップが無い場合、`KC_LALT` が登録解除され、ウィンドウを切り替えることができます。 + +```c +bool is_alt_tab_active = false; # keymap.c の先頭付近にこれを追加します +uint16_t alt_tab_timer = 0; # すぐにそれらを使います + +enum custom_keycodes { # 素晴らしいキーコードを用意してください + ALT_TAB = SAFE_RANGE, +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { # これはキーコードを利用したつまらない作業のほとんどを行います。 + case ALT_TAB: + if (record->event.pressed) { + if (!is_alt_tab_active) { + is_alt_tab_active = true; + register_code(KC_LALT); + } + alt_tab_timer = timer_read(); + register_code(KC_TAB); + } else { + unregister_code(KC_TAB); + } + break; + } + return true; +} + +void matrix_scan_user(void) { # とても重要なタイマー + if (is_alt_tab_active) { + if (timer_elapsed(alt_tab_timer) > 1000) { + unregister_code(KC_LALT); + is_alt_tab_active = false; + } + } +} +``` + +--- + +## **(非推奨)** 古い方法: `MACRO()` と `action_get_macro` + +!> これは TMK から継承されており、更新されていません - 代わりに `SEND_STRING` と `process_record_user` を使うことをお勧めします。 + +デフォルトでは、QMK はマクロが無いことを前提としています。マクロを定義するには、`action_get_macro()` 関数を作成します。例えば: + +```c +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + if (record->event.pressed) { + switch(id) { + case 0: + return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); + case 1: + return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); + } + } + return MACRO_NONE; +}; +``` + +これは割り当てられているキーが押された時に実行される2つのマクロを定義します。キーが放された時にそれらを実行したい場合は、if 文を変更することができます。 + + if (!record->event.pressed) { + +### マクロコマンド + +マクロは以下のコマンドを含めることができます: + +* I() はストロークの間隔をミリ秒単位で変更します。 +* D() はキーを押します。 +* U() はキーを放します。 +* T() はキーをタイプ(押して放す)します。 +* W() は待ちます (ミリ秒)。 +* END 終了マーク。 + +### マクロをキーにマッピングする + +マクロを呼び出すにはキーマップ内で `M()` 関数を使います。例えば、2キーのキーボードのキーマップは以下の通りです: + +```c +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + M(0), M(1) + ), +}; + +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + if (record->event.pressed) { + switch(id) { + case 0: + return MACRO(D(LSFT), T(H), U(LSFT), T(I), D(LSFT), T(1), U(LSFT), END); + case 1: + return MACRO(D(LSFT), T(B), U(LSFT), T(Y), T(E), D(LSFT), T(1), U(LSFT), END); + } + } + return MACRO_NONE; +}; +``` + +左側のキーを押すと、"Hi!" を入力し、右側のキーを押すと "Bye!" を入力します。 + +### マクロに名前を付ける + +キーマップを読みやすくしながらキーマップから参照したいマクロがたくさんある場合は、ファイルの先頭で `#define` を使って名前を付けることができます。 + +```c +#define M_HI M(0) +#define M_BYE M(1) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + M_HI, M_BYE + ), +}; +``` + + +## 高度な例: + +### 単一キーのコピーと貼り付け + +この例は、押された時に `Ctrl-C` を送信し、放される時に `Ctrl-V` を送信するマクロを定義します。 + +```c +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { + switch(id) { + case 0: { + if (record->event.pressed) { + return MACRO( D(LCTL), T(C), U(LCTL), END ); + } else { + return MACRO( D(LCTL), T(V), U(LCTL), END ); + } + break; + } + } + return MACRO_NONE; +}; +``` diff --git a/ja/feature_mouse_keys.md b/ja/feature_mouse_keys.md new file mode 100644 index 00000000000..74b09e939b7 --- /dev/null +++ b/ja/feature_mouse_keys.md @@ -0,0 +1,144 @@ +# マウスキー + + + +マウスキーは、キーボードを使ってマウスをエミュレートできる機能です。様々な速度でポインタを移動し、5つのボタンを押し、8方向にスクロールすることができます。 + +## キーボードにマウスキーを追加 + +マウスキーを使うためには、少なくともマウスキーサポートを有効にし、マウスアクションをキーボードのキーにマップする必要があります。 + +### マウスキーを有効にする + +マウスキーを有効にするには、キーマップの `rules.mk` に以下の行を追加します: + +```c +MOUSEKEY_ENABLE = yes +``` + +### マウスアクションのマッピング + +キーマップでキー押下をマウスアクションにマップするために、以下のキーコードを使うことができます: + +| キー | エイリアス | 説明 | +|----------------|---------|-----------------| +| `KC_MS_UP` | `KC_MS_U` | カーソルを上に移動 | +| `KC_MS_DOWN` | `KC_MS_D` | カーソルを下に移動 | +| `KC_MS_LEFT` | `KC_MS_L` | カーソルを左に移動 | +| `KC_MS_RIGHT` | `KC_MS_R` | カーソルを右に移動 | +| `KC_MS_BTN1` | `KC_BTN1` | ボタン1を押す | +| `KC_MS_BTN2` | `KC_BTN2` | ボタン2を押す | +| `KC_MS_BTN3` | `KC_BTN3` | ボタン3を押す | +| `KC_MS_BTN4` | `KC_BTN4` | ボタン4を押す | +| `KC_MS_BTN5` | `KC_BTN5` | ボタン5を押す | +| `KC_MS_WH_UP` | `KC_WH_U` | ホイールを向こう側に回転 | +| `KC_MS_WH_DOWN` | `KC_WH_D` | ホイールを手前側に回転 | +| `KC_MS_WH_LEFT` | `KC_WH_L` | ホイールを左に倒す | +| `KC_MS_WH_RIGHT` | `KC_WH_R` | ホイールを右に倒す | +| `KC_MS_ACCEL0` | `KC_ACL0` | 速度を0に設定 | +| `KC_MS_ACCEL1` | `KC_ACL1` | 速度を1に設定 | +| `KC_MS_ACCEL2` | `KC_ACL2` | 速度を2に設定 | + +## マウスキーの設定 + +マウスキーはカーソルを移動するための3つの異なるモードをサポートします: + +* **加速 (デフォルト):** 移動キーを押したままにすると、カーソルが最大速度に達するまでカーソルを加速します。 +* **定速:** 移動キーを押したままにすると、カーソルを一定の速度で移動します。 +* **混合:** 移動キーを押したままにすると、カーソルが最大速度に達するまでカーソルを加速し、加速キーと移動キーを同時に押すとカーソルは一定の速度で移動します。 + +同じ原則がスクロールにも適用されます。 + +時間、間隔、遅延の設定オプションは、ミリ秒で指定されます。スクロール速度はデフォルトスクロールステップの倍数として渡されます。例えば、スクロール速度8は、各スクロールアクションがオペレーティングシステムまたはアプリケーションで定義されるデフォルトのスクロールステップの8倍の距離進むことを意味します。 + +### 加速モード + +これはデフォルトのモードです。キーマップの `config.h` ファイルの以下の設定を使ってカーソルとスクロールの加速を調整することができます: + +| 定義 | デフォルト | 説明 | +|----------------------------|-------|---------------------------------------------------------| +| `MOUSEKEY_DELAY` | 300 | 移動キーを押してからカーソルが移動するまでの遅延 | +| `MOUSEKEY_INTERVAL` | 50 | カーソル移動間の時間 | +| `MOUSEKEY_MAX_SPEED` | 10 | 加速が停止する最大のカーソル速度 | +| `MOUSEKEY_TIME_TO_MAX` | 20 | 最大カーソル速度に達するまでの時間 | +| `MOUSEKEY_WHEEL_DELAY` | 300 | ホイールキーを押してからホイールが動くまでの遅延 | +| `MOUSEKEY_WHEEL_INTERVAL` | 100 | ホイールの動きの間の時間 | +| `MOUSEKEY_WHEEL_MAX_SPEED` | 8 | スクロールアクションごとのスクロールステップの最大数 | +| `MOUSEKEY_WHEEL_TIME_TO_MAX` | 40 | 最大スクロール速度に達するまでの時間 | + +ヒント: + +* `MOUSEKEY_DELAY` の設定が低すぎるとカーソルが応答しなくなります。設定が高すぎると小さな動きが難しくなります。 +* カーソルの動きをスムーズにするには、`MOUSEKEY_INTERVAL` の値を低くします。ディスプレイのリフレッシュレートが60Hzの場合、`16` (1/60) に設定することができます。これによりカーソルの速度が大幅に向上するため、`MOUSEKEY_MAX_SPEED` を下げた方が良いかもしれません。 +* `MOUSEKEY_TIME_TO_MAX` または `MOUSEKEY_WHEEL_TIME_TO_MAX` を `0` に設定すると、それぞれカーソルの速度またはスクロールの加速が無効になります。この方法では、一方を加速しながら他方を一定にすることができますが、これは定速モードでは不可能です。 +* `MOUSEKEY_WHEEL_INTERVAL` の設定が低すぎるとスクロールがとても速くなります。設定が高すぎるとホイールキーを押したままにした時にスクロールがとても遅くなります + +カーソルの加速は、X Window System MouseKeysAccel 機能と同じアルゴリズムを使います。詳細については [Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys) をご覧ください。 + +### 定速モード + +このモードでは、カーソルおよびマウスホイールの両方について複数の異なる速度を定義することができます。加速はありません。`KC_ACL0`、`KC_ACL1` および `KC_ACL2` は、カーソルとスクロールの速度をそれぞれの設定に変更します。 + +速度の選択は、一時的とタップ選択のどちらかを選べます: + +* **一時的:** 選択された速度は、それぞれのキーを押している間のみアクティブになります。キーを放すと、マウスキーは変更される前の速度に戻ります。 +* **タップ選択:** それぞれのキーを押すと選択された速度がアクティブになり、キーを放した後もアクティブのままになります。デフォルトの速度は `KC_ACL1` です。未変更の速度はありません。 + +最も遅い速度から最も速い速度までのデフォルトの速度は以下の通りです: + +* **一時的:** `KC_ACL0` < `KC_ACL1` < *変更無し* < `KC_ACL2` +* **タップ選択:** `KC_ACL0` < `KC_ACL1` < `KC_ACL2` + +定速モードを使うには、少なくともキーマップの keymaps ディレクトリの `config.h` ファイルに `MK_3_SPEED` を定義する必要があります。 + +```c +#define MK_3_SPEED +``` + +一時的モードを有効にするには、`MK_MOMENTARY_ACCEL` も定義します: + +```c +#define MK_MOMENTARY_ACCEL +``` + +カーソル移動あるいはスクロールを調整する場合は、以下の設定を使います: + +| 定義 | デフォルト | 説明 | +|---------------------|-------------|-------------------------------------------| +| `MK_3_SPEED` | *定義なし* | 定速カーソルを有効にする | +| `MK_MOMENTARY_ACCEL` | *定義なし* | 一時的モードを有効にする | +| `MK_C_OFFSET_UNMOD` | 16 | 移動ごとのカーソルオフセット (変更無し) | +| `MK_C_INTERVAL_UNMOD` | 16 | カーソルの移動間の時間 (変更無し) | +| `MK_C_OFFSET_0` | 1 | 移動ごとのカーソルオフセット (`KC_ACL0`) | +| `MK_C_INTERVAL_0` | 32 | カーソル移動間の時間 (`KC_ACL0`) | +| `MK_C_OFFSET_1` | 4 | 移動ごとのカーソルオフセット (`KC_ACL1`) | +| `MK_C_INTERVAL_1` | 16 | カーソル移動間の時間 (`KC_ACL1`) | +| `MK_C_OFFSET_2` | 32 | 移動ごとのカーソルオフセット (`KC_ACL2`) | +| `MK_C_INTERVAL_2` | 16 | カーソル移動間の時間 (`KC_ACL2`) | +| `MK_W_OFFSET_UNMOD` | 1 | スクロールアクションごとのスクロールステップ (変更無し) | +| `MK_W_INTERVAL_UNMOD` | 40 | スクロールステップ間の時間 (変更無し) | +| `MK_W_OFFSET_0` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL0`) | +| `MK_W_INTERVAL_0` | 360 | スクロールステップ間の時間 (`KC_ACL0`) | +| `MK_W_OFFSET_1` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL1`) | +| `MK_W_INTERVAL_1` | 120 | スクロールステップ間の時間 (`KC_ACL1`) | +| `MK_W_OFFSET_2` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL2`) | +| `MK_W_INTERVAL_2` | 20 | スクロールステップ間の時間 (`KC_ACL2`) | + +### 混合モード + +このモードは **加速** モードのように機能しますが、`KC_ACL0`、`KC_ACL1`、`KC_ACL2` を押したままにすることで +一時的(押している間)にカーソルとスクロール速度を定速に設定できます。 +加速キーが押されていない場合、このモードは **加速** モードと同じで、関連する全ての設定を使って変更できます。 + +* **KC_ACL0:** この加速はカーソルをできるだけ遅い速度に設定します。これはカーソルを非常に小さく詳細に移動する場合に便利です。 +* **KC_ACL1:** この加速はカーソルを最大(ユーザ定義)速度の半分に設定します。 +* **KC_ACL2:** この加速はカーソルを最大(コンピュータ定義)速度に設定します。これは、正確性を多少犠牲にしてカーソルを大きく移動する場合に便利です。 + +混合モードを使うには、キーマップの `config.h` ファイルに少なくとも `MK_COMBINED` を定義しなければなりません: + +```c +#define MK_COMBINED +``` diff --git a/ja/feature_pointing_device.md b/ja/feature_pointing_device.md new file mode 100644 index 00000000000..f606036d149 --- /dev/null +++ b/ja/feature_pointing_device.md @@ -0,0 +1,54 @@ +# ポインティングデバイス :id=pointing-device + + + +ポインティングデバイスは汎用的な機能の総称です: システムポインタを移動します。マウスキーのような他のオプションも確かにありますが、これは簡単に変更可能で軽量であることを目指しています。機能を制御するためにカスタムキーを実装したり、他の周辺機器から情報を収集してここに直接挿入したりできます - QMK に処理を任せてください。 + +ポインティングデバイスを有効にするには、rules.mk の以下の行のコメントを解除します: + +```makefile +POINTING_DEVICE_ENABLE = yes +``` + +マウスレポートを操作するために、以下の関数を使うことができます: + +* `pointing_device_get_report()` - ホストコンピュータに送信された情報を表す現在の report_mouse_t を返します。 +* `pointing_device_set_report(report_mouse_t newMouseReport)` - ホストコンピュータに送信される report_mouse_t を上書き保存します。 + +report_mouse_t (ここでは "mouseReport") が以下のプロパティを持つことを覚えておいてください: + +* `mouseReport.x` - これは、x軸の動き(+ 右へ、- 左へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 +* `mouseReport.y` - これは、y軸の動き(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 +* `mouseReport.v` - これは、垂直スクロール(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 +* `mouseReport.h` - これは、水平スクロール(+ 右へ、- 左へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 +* `mouseReport.buttons` - これは uint8_t で、上位の5ビットを使っています。これらのビットはマウスボタンの状態を表します - ビット 3 はマウスボタン 5、ビット 7 はマウスボタン 1 です。 + +マウスレポートに必要な変更を行ったら、それを送信する必要があります: + +* `pointing_device_send()` - マウスレポートをホストに送信し、レポートをゼロにします。 + +マウスレポートが送信されると、x、y、v、h のいずれの値も 0 に設定されます (これは `pointing_device_send()` で行われます。この挙動を回避するためにオーバーライドすることができます)。このように、ボタンの状態は持続しますが、動きは1度だけ起こります。さらにカスタマイズするために、`pointing_device_init` と `pointing_device_task` のどちらもオーバーライドすることができます。 + +以下の例では、カスタムキーを使ってマウスをクリックし垂直および水平方向に127単位スクロールし、リリースされた時にそれを全て元に戻します - なぜならこれは完全に便利な機能だからです。いいですか、以下はひとつの例です: + +```c +case MS_SPECIAL: + report_mouse_t currentReport = pointing_device_get_report(); + if (record->event.pressed) { + currentReport.v = 127; + currentReport.h = 127; + currentReport.buttons |= MOUSE_BTN1; // this is defined in report.h + } else { + currentReport.v = -127; + currentReport.h = -127; + currentReport.buttons &= ~MOUSE_BTN1; + } + pointing_device_set_report(currentReport); + pointing_device_send(); + break; +``` + +マウスレポートは送信されるたびに 0 (ボタンを除く)に設定されることを思い出してください。そのため、スクロールはそれぞれの場合に1度だけ発生します。 diff --git a/ja/feature_ps2_mouse.md b/ja/feature_ps2_mouse.md new file mode 100644 index 00000000000..0351768b33d --- /dev/null +++ b/ja/feature_ps2_mouse.md @@ -0,0 +1,303 @@ +# PS/2 マウスサポート :id=ps2-mouse-support + + + +PS/2 マウス (例えばタッチパッドあるいはトラックポイント)を複合デバイスとしてキーボードに接続することができます。 + +トラックポイントを接続するには、トラックポイントモジュールを入手し (つまり、Thinkpad キーボードから部品を取って)、モジュールの各ピンの機能を特定し、コントローラとトラックポイントモジュールの間に必要な回路を作成する必要があります。詳細については、Deskthority Wiki の[トラックポイントハードウェア](https://deskthority.net/wiki/TrackPoint_Hardware)ページを参照してください。 + +PS/2 デバイスの接続は、USART(最善)、割り込み(次善)、 または busywait(非推奨)の3つのやり方が有ります。 + +## トラックポイントとコントローラ間の回路 :id=the-circuitry-between-trackpoint-and-controller + +動作させるには、DATA と CLK のふたつのラインを 4.7k の抵抗で 5V にプルアップしてやる必要があります。 + +``` + DATA ----------+--------- PIN + | + 4.7K + | +MODULE 5+ --------+--+--------- PWR CONTROLLER + | + 4.7K + | + CLK ------+------------ PIN +``` + + +## Busywait バージョン :id=busywait-version + +注意: これは非推奨です。ギクシャクした動きや、未送信の入力が発生するかもしれません。可能であれば、割り込みまたは USART バージョンを使ってください。 + +rules.mk で: + +```makefile +PS2_MOUSE_ENABLE = yes +PS2_USE_BUSYWAIT = yes +``` + +キーボードの config.h で: + +```c +#ifdef PS2_USE_BUSYWAIT +# define PS2_CLOCK_PORT PORTD +# define PS2_CLOCK_PIN PIND +# define PS2_CLOCK_DDR DDRD +# define PS2_CLOCK_BIT 1 +# define PS2_DATA_PORT PORTD +# define PS2_DATA_PIN PIND +# define PS2_DATA_DDR DDRD +# define PS2_DATA_BIT 2 +#endif +``` + +## 割り込みバージョン :id=interrupt-version + +以下の例はクロックのために D2 を、データのために D5 を使います。クロックには任意の INT あるいは PCINT ピンを、データには任意のピンを使うことができます。 + +rules.mk で: + +```makefile +PS2_MOUSE_ENABLE = yes +PS2_USE_INT = yes +``` + +キーボードの config.h で: + +```c +#ifdef PS2_USE_INT +#define PS2_CLOCK_PORT PORTD +#define PS2_CLOCK_PIN PIND +#define PS2_CLOCK_DDR DDRD +#define PS2_CLOCK_BIT 2 +#define PS2_DATA_PORT PORTD +#define PS2_DATA_PIN PIND +#define PS2_DATA_DDR DDRD +#define PS2_DATA_BIT 5 + +#define PS2_INT_INIT() do { \ + EICRA |= ((1< + +QMK ファームウェアリポジトリの多くのキーボードは、"分割"キーボードです。それらは2つのコントローラを使います — 1つは USB に接続し、もう1つは TRRS または同様のケーブルを介してシリアルまたは I2C 接続で接続します。 + +分割キーボードには多くの利点がありますが、有効にするには追加の作業が必要です。 + +QMK ファームウェアには、任意のキーボードで使用可能な一般的な実装と、多くのキーボード固有の実装があります。 + +このため、主に Let's Split とその他のキーボードで使われる一般的な実装について説明します。 + +!> ARM はまだ完全には分割キーボードをサポートしておらず、様々な制限があります。進捗はしていますが、機能の100%にはまだ達していません。 + + +## 互換性の概要 + +| Transport | AVR | ARM | +|------------------------------|--------------------|--------------------| +| ['serial'](ja/serial_driver.md) | :heavy_check_mark: | :white_check_mark: 1 | +| I2C | :heavy_check_mark: | | + +注意: + +1. ハードウェアとソフトウェアの両方の制限は、[ドライバーのドキュメント](ja/serial_driver.md)の中で説明されます。 + +## ハードウェア設定 + +2つの Pro Micro 互換のコントローラを使っており、キーボードの左右を接続するために TRRS ジャックを使っていることを前提とします。 + +### ハードウェア要件 + +左右それぞれのキーボードマトリックスのためのダイオードとスイッチとは別に、2個の TRRS ソケットと 1本の TRRS ケーブルが必要です。 + +あるいは、少なくとも3本のワイヤがあるケーブルとソケットを使うことができます。 + +キーボードの左右間で通信するために I2C を使いたい場合は、少なくとも4本のワイヤを備えたケーブルと 2個の 4.7kΩ プルアップ抵抗が必要です。 + +#### 考慮事項 + +最も一般的に使われる接続は、TRRS ケーブルとジャックです。これらは4本のワイヤを提供し、分割キーボードに非常に有用で、簡単に見つけることができます。 + +ただし、ワイヤのうちの1本が Vcc を供給するため、キーボードはホットプラグ不可能です。TRRS ケーブルを抜き差しする前に、必ずキーボードのUSB接続をはずす必要があります。そうしなければ、コントローラを短絡させたり、もっと悪いことが起こるかもしれません。 + +別のオプションは電話ケーブルを使うことです (例えば、旧式の RJ-11/RJ-14 ケーブル)。実際に4本のワイヤ/レーンをサポートするものを使うようにしてください。 + +ただし、USB ケーブル、SATA ケーブル、そして単に4本の電線でもコントローラ間の通信に使用できることがわかっています。 + +!> コントローラ間の通信に USB ケーブルを使っても問題ありませんが、コネクタは通常の USB 接続と間違えられるかもしれず、配線方法によってはキーボードが短絡する可能性があります。このため、分割キーボードの接続のためにはお勧めできません。 + +### シリアル配線 + +2つの Pro Micro 間で GND、Vcc、D0/D1/D2/D3 (別名 PD0/PD1/PD2/PD3) を TRS/TRRS ケーブルの3本のワイヤで接続します。 + +?> ここで使われるピンは実際には以下の `SOFT_SERIAL_PIN` によって設定されることに注意してください。 + +sk-pd0-connection-mono +sk-pd2-connection-mono + +### I2C 配線 + +2つの Pro Micro 間で GND、Vcc、さらに SCL と SDA (それぞれ 別名 PD0/ピン3 および PD1/ピン2) を TRRS ケーブルの4本のワイヤで接続します。 + +プルアップ抵抗はキーボードの左右どちら側にも配置することができます。もし各側を単独で使いたい場合は、4つの抵抗を使い、両側にプルアップ抵抗を配置することもできます。 + +sk-i2c-connection-mono + +## ファームウェア設定 + +分割キーボード機能を有効にするには、以下を `rules.mk` に追加してください: + +```make +SPLIT_KEYBOARD = yes +``` + +カスタムトランスポート (通信メソッド)を使っている場合は、以下を追加する必要もあります: + +```make +SPLIT_TRANSPORT = custom +``` + +### 左右の設定 + +デフォルトでは、ファームウェアはどちら側がどちらであるかを認識しません; 決定するには幾つかの助けが必要です。これを行うには幾つかの方法があり、以下に優先順に列挙します。 + +#### ピンによる左右の設定 + +左右を決定するためにコントローラ上のピンを読むようにファームウェアを設定することができます。これを行うには、以下を `config.h` ファイルに追加します: + +```c +#define SPLIT_HAND_PIN B7 +``` + +これは指定されたピンを読み込みます。high の場合、コントローラはそれを左側だと仮定し、low の場合、それは右側であると仮定します。 + +#### マトリックスピンによる左右の設定 + +左右を決定するためにコントローラのキーマトリックスピンを読むようにファームウェアを設定することができます。これを行うには、以下を `config.h` ファイルに追加します: + +```c +#define SPLIT_HAND_MATRIX_GRID D0, F1 +``` + +最初のピンは出力ピンで、2つ目は入力ピンです。 + +キーマトリックスに未使用の交点があるキーボードがあります。この設定は、左右の決定にこれらの未使用の交点の1つを使用します。 + +通常、ダイオードが交点に接続されている場合、左側と判断されます。次の定義を追加すると、右側と判断されます。 + +```c +#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT +``` + +#### EEPROM による左右の設定 + +このメソッドは永続ストレージ(`EEPROM`)のフラグを設定することで、キーボードの左右を設定します。これはコントローラが最初に起動する時にチェックされ、キーボードのどちら側であるかとキーボードのレイアウトの向きを決定します。 + + +このメソッドを有効にするには、以下を `config.h` ファイルに追加します: + +```c +#define EE_HANDS +``` + +ただし、各コントローラに正しい側の EEPROM ファイルを書き込む必要があります。これを手動で行うこともできますが、ファームウェアを書き込む時にこれを行う avrdude および dfu のターゲットが存在します。 + +* `:avrdude-split-left` +* `:avrdude-split-right` +* `:dfu-split-left` +* `:dfu-split-right` +* `:dfu-util-split-left` +* `:dfu-util-split-right` + +この設定は、`EEP_RST` キーや `eeconfig_init()` 関数を使って EEPROM を再初期化する時には変更されません。ただし、ファームウェアの組み込みオプション以外で EEPROM をリセット([QMK Toolbox]() の "Reset EEPROM" ボタンの動作のように、`EEPROM` を上書きするファイルを書きこむなど)した場合、`EEPROM` ファイルを再書き込みする必要があります。 + +`EEPROM` ファイルは、QMK ファームウェアのリポジトリ内の[ここ](https://github.com/qmk/qmk_firmware/tree/master/quantum/split_common)にあります。 + +#### `#define` による左右の設定 + +コンパイル時に左右を設定することができます。これは以下を `config.h` ファイルに追加することで行うことができます: + +```c +#define MASTER_RIGHT +``` + +あるいは + +```c +#define MASTER_LEFT +``` + +どちらも定義されていない場合、左右のデフォルトは `MASTER_LEFT` になります。 + + +### 通信オプション + +全ての分割キーボードが同一であるとは限らないため、`config.h` ファイル内で設定することができる多くの追加のオプションがあります。 + +```c +#define USE_I2C +``` + +これは分割キーボードの I2C サポートを有効にします。これは厳密には通信用ではありませんが、OLED あるいは I2C ベースのデバイスに使うことができます。 + +```c +#define SOFT_SERIAL_PIN D0 +``` + +これはシリアル通信用に使われるピンを設定します。シリアルを使っていない場合は、これを定義する必要はありません。 + +ただし、キーボード上でシリアルおよび I2C を使っている場合は、これを設定し、D0 および D1 以外の値に設定する必要があります (これらは I2C 通信のために使われます)。 + +```c +#define SELECT_SOFT_SERIAL_SPEED {#}` +``` + +シリアル通信に問題がある場合は、この値を変更して、シリアル用の通信速度を制御することができます。デフォルトは1で、可能な値は以下の通りです: + +* **`0`**: 約189kbps (実験用途専用) +* **`1`**: 約137kbps (デフォルト) +* **`2`**: 約75kbps +* **`3`**: 約39kbps +* **`4`**: 約26kbps +* **`5`**: 約20kbps + +### ハードウェア設定オプション + +ハードウェアのセットアップ方法に基づいて、設定する必要のある設定が幾つかあります。 + +```c +#define MATRIX_ROW_PINS_RIGHT { } +#define MATRIX_COL_PINS_RIGHT { } +``` + +これにより、右側のマトリックスに異なるピンのセットを指定することができます。これは、左右の形が違うキーボード (Keebio の Quefrency など)で、左右で別の構成が必要な場合に便利です。 + +```c +#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } } +``` + +これにより右側のための異なる直接ピンのセットを指定することができます。 + +```c +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +``` + +これにより右側のための異なるエンコーダピンのセットを指定することができます。 + +```c +#define RGBLIGHT_SPLIT +``` + +このオプションは、分割キーボードのコントローラ間で RGB ライトモードの同期を有効にします。これはコントローラに直接配線されている RGB LED を持つキーボード用です (つまり、それらは TRRS ケーブルで "追加データ"オプションを使っていません)。 + +```c +#define RGBLED_SPLIT { 6, 6 } +``` + +これは各コントローラに直接接続されている LED の数を設定します。最初の数は左側、2番目の数は右側です。 + +?> この設定は `RGBLIGHT_SPLIT` が有効になっていることを意味し、有効になっていない場合は強制的に有効にします。 + + +```c +#define SPLIT_USB_DETECT +``` +このオプションは、スタートアップの挙動を変更して、マスタ/スレーブの決定時にアクティブな USB 接続を検出します。このオプションがタイムアウトになった場合、その片側はスレーブと見なされます。これは ARM のデフォルトの挙動で、AVR Teensy ボードに必要です (ハードウェアの制限のため)。 + +?> この設定はバッテリパックを使ったデモの機能を停止します。 + +```c +#define SPLIT_USB_TIMEOUT 2000 +``` +これは、`SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合の最大タイムアウトを設定します。 + +```c +#define SPLIT_USB_TIMEOUT_POLL 10 +``` +これは `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合のポーリング頻度を設定します + +## 追加のリソース(英語) + +Nicinabox には Let's Split キーボードのための[非常に優れた詳細なガイド](https://github.com/nicinabox/lets-split-guide)があり、トラブルシューティング情報を含む知っておくべきほとんど全てをカバーします。 + +ただし、RGB ライトセクションは、RGB Split コードが QMK ファームウェアに追加されるずっと前に書かれたため、古くなっています。ガイドに従う代わりに、各 LED テーブ(訳注: LED strip とも呼びます)を直接コントローラに配線します。 + + diff --git a/ja/feature_stenography.md b/ja/feature_stenography.md new file mode 100644 index 00000000000..45a799be494 --- /dev/null +++ b/ja/feature_stenography.md @@ -0,0 +1,136 @@ +# QMK での速記 :id=stenography-in-qmk + + + +[速記](https://en.wikipedia.org/wiki/Stenotype)は裁判所のレポート、字幕および耳が不自由な人のためのリアルタイムの文字起こしで最もよく使われる記述方法です。速記では単語はスペル、音声およびショートカット(短い)ストロークが混在する音節ごとに音節化されます。プロの速記者は、標準的なタイピングで通常見られる負担を掛けずに、はるかに少ないエラー(99.9%より高い精度)で、200-300 WPM に到達できます。 + +[Open Steno Project](http://www.openstenoproject.org/)は、速記ストロークを単語とコマンドにリアルタイムに変換する Plover と呼ばれるオープンソースプログラムを構築しました。確立された辞書とサポートがあります。 + +## QWERTY キーボードを使った Plover :id=plover-with-qwerty-keyboard + +Plover は全ての標準的な QWERTY キーボードで動作しますが、キーボードが NKRO (n-キーロールオーバー)をサポートする場合は Plover は一度に押された全てのキーが分かるためより効率的です。Plover 用のキーマップの例は `planck/keymaps/default` で見つかります。`PLOVER` レイヤーに切り替えると、数字バーをサポートするためにキーボードの位置が調整されます。 + +QMK で Plover を使うには、NKRO を有効にし、標準レイアウト以外のレイアウトの場合はオプションでレイアウトを調整します。複数のキーを押しやすくするために、なんらかの速記フレンドリなキーキャップを購入することもできます。 + +## 速記プロトコルを使った Plover :id=plover-with-steno-protocol + +Plover は幾つかの速記マシンの言語も理解します。QMK はこれらの言語の内2つの言語、TX Bolt と GeminiPR を話すことができます。レイアウトの例は `planck/keymaps/steno` で見つけることができます。 + +QMKが steno プロトコルを使って Plover と話す場合は、Plover は入力としてキーボードを使いません。標準のキーボードと速記キーボードを行き来したり、あるいは Plover をアクティブ/非アクティブにする必要なく Plover と標準のレイヤーを行き来することができることを意味します。 + +このモードでは、Plover はシリアルポートを介して速記マシンと通信すると想定しているため、QMK はオペレーティングシステムに対してキーボードに加えて仮想シリアルポートとして存在しています。デフォルトでは、QMK は TX Bolt プロトコルを話しますが、GeminiPR に切り替えることができます; 最後に使われたプロトコルが不揮発性メモリに格納されるため QMK は再起動時に同じプロトコルを使います。 + +> 注意: ハードウェアの制限により、仮想シリアルポートとマウスエミュレーションの両方を同時に実行することができないかもしれません。 + +### TX Bolt :id=tx-bolt + +TX Bolt は可変サイズ(1-5バイト)のパケットで非常に単純なプロトコルを介して24個のキーのステータスを通信します。 + +### GeminiPR :id=geminipr + +GeminiPR は42個のキーを6バイトのパケットにエンコードします。TX Bolt は標準的な速記に必要な全てを含んでいますが、GeminiPR は英語以外の速記法のサポートを含む、より多くのオプションにも開け放たれています。 + +## 速記のための QMK の設定 :id=configuring-qmk-for-steno + +最初にキーマップの Makefile で速記を有効にします。競合を避けるために、マウスキー、追加キーあるいはその他の USB エンドポイントを無効にする必要もあります。幾つかのプロセッサの内蔵の USB スタックは一定数の USB エンドポイントと仮想シリアルポートのみをサポートし、速記はそれらのうちの3つを使います。 + +```makefile +STENO_ENABLE = yes +MOUSEKEY_ENABLE = no +``` + +キーマップで Plover 用の新しいレイヤーを作成します。`keymap_steno.h` をインクルードする必要があります。例については `planck/keymaps/steno/keymap.c` を見てください。レイヤーに切り替えるためのキーとレイヤーから抜けるためのキーを作成することを忘れないでください。その場でモードを切り替えたい場合は、キーコード `QK_STENO_BOLT` および `QK_STENO_GEMINI` を使うことができます。プロトコルのうちの1つのみを使う場合は、初期化関数の中でそれをセットアップすることができます: + +```c +void matrix_init_user() { + steno_set_mode(STENO_MODE_GEMINI); // あるいは STENO_MODE_BOLT +} +``` + +キーボードを書き込んだら、Plover を起動します。'Configure...' ボタンをクリックします。'Machine' タブの中で目的のプロトコルに対応する速記マシンを選択します。このタブの 'Configure...' ボタンをクリックし、シリアルポートを入力するか 'Scan' をクリックします。ボーレートは 9600 で問題ありません (ただし、115200まで問題無く設定することができるはずです)。それ以外はデフォルトの設定(データビット長: 8、ストップビット長: 1、パリティチェック: なし、フロー制御なし)を使います。 + +ディスプレイタブで 'Open stroke display' をクリックします。Plover を無効にすると、キーボードのキーを押すとストローク表示ウィンドウにそれらが表示されるはずです。これを使ってキーマップが正しくセットアップされたことを確認してください。これで速記をする準備ができました! + +## 速記の学習 :id=learning-stenography + +* [Learn Plover!](https://sites.google.com/site/learnplover/) +* [QWERTY Steno](http://qwertysteno.com/Home/) +* [Steno Jig](https://joshuagrams.github.io/steno-jig/) +* Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki のより多くのリソース + +## コードとのインターフェイス :id=interfacing-with-the-code + +速記コードには3つの捕捉可能なフックがあります。これらの関数を定義した場合、処理の特定のポイントでそれらが呼び出されます; それらが true を返す場合処理が継続され、そうでなければあなたが物事を処理すると想定します。 + +```c +bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]); +``` + +この関数はコードが送信されようとしている時に呼ばれます。モードは `STENO_MODE_BOLT` あるいは `STENO_MODE_GEMINI` のいずれかです。これはいずれかのプロトコルを介して送信される実際のコードを表します。提供されるコードを修正して送信されるものを変更することができます。通常の送信プロセスにしたい場合は true を返すのを忘れないでください。 + +```c +bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } +``` + +この関数はキーが押されるとキーが処理される前に呼び出されます。キーコードは `QK_STENO_BOLT`、`QK_STENO_GEMINI` あるいは `STN_*` キー値のいずれかでなければなりません。 + +```c +bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed); +``` + +この関数はキーが処理された後、ただしコードを送信するかどうかを決める前に呼び出されます。`IS_PRESSED(record->event)` が false で、`pressed` が 0 または 1 の場合は、コードはまもなく送信されますが、まだ送信されてはいません。ここが速記コードあるいはキーのライブ表示などのフックを配置する場所です。 + + +## キーコードリファレンス :id=keycode-reference + +`keymap_steno.h` で定義されています。 + +> 注意: TX Bolt はキーの完全なセットをサポートしません。QMK での TX Bolt の実装は、GeminiPR キーを最も近い TX Bolt キーにマップします。そのため1つのキーマップが両方で動作します。 + +| GeminiPR | TX Bolt | Steno Key | +|--------|-------|-----------| +| `STN_N1` | `STN_NUM` | Number bar #1 | +| `STN_N2` | `STN_NUM` | Number bar #2 | +| `STN_N3` | `STN_NUM` | Number bar #3 | +| `STN_N4` | `STN_NUM` | Number bar #4 | +| `STN_N5` | `STN_NUM` | Number bar #5 | +| `STN_N6` | `STN_NUM` | Number bar #6 | +| `STN_N7` | `STN_NUM` | Number bar #7 | +| `STN_N8` | `STN_NUM` | Number bar #8 | +| `STN_N9` | `STN_NUM` | Number bar #9 | +| `STN_NA` | `STN_NUM` | Number bar #A | +| `STN_NB` | `STN_NUM` | Number bar #B | +| `STN_NC` | `STN_NUM` | Number bar #C | +| `STN_S1` | `STN_SL` | `S-` upper | +| `STN_S2` | `STN_SL` | `S-` lower | +| `STN_TL` | `STN_TL` | `T-` | +| `STN_KL` | `STN_KL` | `K-` | +| `STN_PL` | `STN_PL` | `P-` | +| `STN_WL` | `STN_WL` | `W-` | +| `STN_HL` | `STN_HL` | `H-` | +| `STN_RL` | `STN_RL` | `R-` | +| `STN_A` | `STN_A` | `A` vowel | +| `STN_O` | `STN_O` | `O` vowel | +| `STN_ST1` | `STN_STR` | `*` upper-left | +| `STN_ST2` | `STN_STR` | `*` lower-left | +| `STN_ST3` | `STN_STR` | `*` upper-right | +| `STN_ST4` | `STN_STR` | `*` lower-right | +| `STN_E` | `STN_E` | `E` vowel | +| `STN_U` | `STN_U` | `U` vowel | +| `STN_FR` | `STN_FR` | `-F` | +| `STN_PR` | `STN_PR` | `-P` | +| `STN_RR` | `STN_RR` | `-R` | +| `STN_BR` | `STN_BR` | `-B` | +| `STN_LR` | `STN_LR` | `-L` | +| `STN_GR` | `STN_GR` | `-G` | +| `STN_TR` | `STN_TR` | `-T` | +| `STN_SR` | `STN_SR` | `-S` | +| `STN_DR` | `STN_DR` | `-D` | +| `STN_ZR` | `STN_ZR` | `-Z` | +| `STN_FN` | (GeminiPR のみ) | +| `STN_RES1` | (GeminiPR のみ) | +| `STN_RES2` | (GeminiPR のみ) | +| `STN_PWR` | (GeminiPR のみ) | diff --git a/ja/feature_swap_hands.md b/ja/feature_swap_hands.md new file mode 100644 index 00000000000..3150801c554 --- /dev/null +++ b/ja/feature_swap_hands.md @@ -0,0 +1,36 @@ +# スワップハンドアクション + + + +スワップハンドアクションにより、別のレイヤーを必要とせずに片手入力をサポートします。Makefile に `SWAP_HANDS_ENABLE` を設定し、キーマップに `hand_swap_config` エントリを定義します。これで `ACTION_SWAP_HANDS` コマンドキーが押されるたびにキーボードがミラーされます。例えば、QWERTY で "Hello, World" を入力するには、`^Ge^s^s^w^c W^wr^sd` を入力します。 + +## 設定 + +設定テーブルは列/行から新しい列/行にマップするための単純な2次元配列です。Planck の `hand_swap_config` の例: + +```C +const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { + {{11, 0}, {10, 0}, {9, 0}, {8, 0}, {7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, + {{11, 1}, {10, 1}, {9, 1}, {8, 1}, {7, 1}, {6, 1}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, + {{11, 2}, {10, 2}, {9, 2}, {8, 2}, {7, 2}, {6, 2}, {5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, + {{11, 3}, {10, 3}, {9, 3}, {8, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, +}; +``` + +配列のインデックスはマトリックスと同様に逆になり、値の型は `{col, row}` である `keypos_t` で、全ての値はゼロベースであることに注意してください。上の例では、`hand_swap_config[2][4]` (第3行, 第5列)は `{7, 2}` (第3行, 第8列) を返します。はい。紛らわしいです。 + +## キーコードの入れ替え + +| キー | 説明 | +|-----------|-------------------------------------------------------------------------| +| `SH_T(key)` | タップで `key` を送信する。押している時の一時的な入れ替え。 | +| `SH_ON` | 入れ替えをオンにして、そのままにする。 | +| `SH_OFF` | 入れ替えをオフにして、そのままにする。既知の状態に戻るのに適しています。 | +| `SH_MON` | 押すとスワップハンドし、放すと通常に戻る (一時的)。 | +| `SH_MOFF` | 一時的に入れ替えをオフする。 | +| `SH_TG` | キーを押すたびに入れ替えのオンとオフを切り替える。 | +| `SH_TT` | タップで切り替える。押されている時の一時的なもの。 | +| `SH_OS` | ワンショットスワップハンド: 押されている時あるいは次のキーを押すまで切り替える。 | diff --git a/ja/feature_tap_dance.md b/ja/feature_tap_dance.md new file mode 100644 index 00000000000..3d9d30ecf02 --- /dev/null +++ b/ja/feature_tap_dance.md @@ -0,0 +1,527 @@ +# タップダンス: 1つのキーが3つ、5つまたは100の異なる動作をします + + + +## イントロダクション :id=introduction + +セミコロンキーを1回叩くと、セミコロンが送信されます。2回素早く叩くと、コロンが送信されます。3回叩くと、あなたのキーボードのLEDが激しく踊るように明滅します。これは、タップダンスでできることの一例です。それは、コミュニティが提案したとても素敵なファームウェアの機能の1つで、[algernon](https://github.com/algernon) がプルリクエスト [#451](https://github.com/qmk/qmk_firmware/pull/451) で考えて作ったものです。algernon が述べる機能は次の通りです: + +この機能を使うと、特定のキーが、タップした回数に基づいて異なる振る舞いをします。そして、割り込みがあった時は、割り込み前に上手く処理されます。 + +## タップダンスの使い方 :id=how-to-use +最初に、あなたの `rules.mk` ファイルで `TAP_DANCE_ENABLE = yes` と設定する必要があります。なぜならば、デフォルトでは無効になっているからです。これでファームウェアのサイズが1キロバイトほど増加します。 + +オプションで、あなたの `config.h` ファイルに次のような設定を追加して、`TAPPING_TERM` の時間をカスタマイズしたほうが良いです。 + +```c +#define TAPPING_TERM 175 +``` + +`TAPPING_TERM` の時間は、あなたのタップダンスのキーのタップとタップの間の時間として許可された最大の時間で、ミリ秒単位で計測されます。例えば、もし、あなたがこの上にある `#define` ステートメントを使い、1回タップすると `Space` が送信され、2回タップすると `Enter` が送信されるタップダンスキーをセットアップした場合、175ミリ秒以内に2回キーをタップすれば `ENT` だけが送信されるでしょう。もし、1回タップしてから175ミリ秒以上待ってからもう一度タップすると、`SPC SPC` が送信されます。 + +次に、いくつかのタップダンスのキーを定義するためには、`TD()` マクロを使うのが最も簡単です。これは数字を受け取り、この数字は後で `tap_dance-actions` 配列のインデックスとして使われます。 + +その後、`tap_dance_actions` 配列を使って、タップダンスキーを押した時のアクションを定義します。現在は、5つの可能なオプションがあります: + +* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: 1回タップすると `kc1` キーコードを送信し、2回タップすると `kc2` キーコードを送信します。キーを押し続けているときは、適切なキーコードが登録されます: キーを押し続けた場合は `kc1`、一度タップしてから続けてもう一度キーを押してそのまま押し続けたときは、 `kc2` が登録されます。 +* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` レイヤーに移動します(これは `TO` レイヤーキーコードのように機能します)。 + * この機能は `ACTION_TAP_DANCE_DUAL_ROLE` と同じですが、機能が明確になるように関数名を変更しました。どちらの関数名でも実行できます。 +* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` の状態をトグルします(これは `TG` レイヤーキーコードのように機能します)。 +* `ACTION_TAP_DANCE_FN(fn)`: ユーザーキーマップに定義した指定の関数が呼び出されます。タップダンス実行の回数分タップすると、最後の時点で呼び出されます。 +* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: タップする度にユーザーキーマップに定義した最初の関数が呼び出されます。タップダンスの実行が終わった時点で2番目の関数が呼び出され、タップダンスの実行をリセットするときに最後の関数が呼び出されます。 +* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: これは `ACTION_TAP_DANCE_FN_ADVANCED` 関数と同じように機能します。しかし、`TAPPING_TERM` で事前に定義した時間の代わりに、カスタマイズしたタップ時間を使います。 + * [ここ](ja/custom_quantum_functions.md#Custom_Tapping_Term)で概説するように、これはキーごとのタッピング時間機能を優先して非推奨になりました。この特定のタップダンス機能を使う代わりに、使いたい特定の `TD()` マクロ(`TD(TD_ESC_CAPS)` のような)を確認する必要があります。 + + +最初のオプションで、1つのキーに2つの役割を持たせる大抵のケースには十分です。例えば、`ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` は、1回タップすると `Space` を送信し、2回タップすると `Enter` を送信します。 + +!> ここでは [基本的なキーコード](ja/keycodes_basic.md) だけがサポートされていることを覚えておいてください。カスタムキーコードはサポートされていません。 + +最初のオプションに似ていますが、2番目のオプションは単純なレイヤー切替のケースに適しています。 + +これ以上に複雑なケースの場合、3番目か4番目のオプションを使います。(以下でそれらの例を列挙します) + +最後に、5番目のオプションは、もし、タップダンスキーをコードに追加した後、非タップダンスキーが奇妙な振る舞いを始めた時に特に役に立ちます。ありうる問題は、あなたがタップダンスキーを使いやすくするために `TAPPING_TERM` の時間を変更した結果、その他のキーが割り込みを処理する方法が変わってしまったというものです。 + + +## 実装の詳細 :id=implementation + +さて、説明の大部分はここまでです! 以下に挙げているいくつかの例に取り組むことができるようになり、あなた自身のタップダンスの機能を開発できるようになります。しかし、もし、あなたが裏側で起きていることをより深く理解したいのであれば、続けてそれが全てどのように機能するかの説明を読みましょう! + +メインエントリーポイントは、`process_tap_dance()` で、`process_record_quantum()` から呼び出されます。これはキーを押すたびに実行され、ハンドラは早期に実行されます。この関数は、押されたキーがタップダンスキーがどうか確認します。 +もし、押されたキーがタップダンスキーではなく、かつ、タップダンスが実行されていたなら、最初にそれを処理し、新しく押されたキーをキューに格納します。 +もし、押されたキーがタップダンスキーであるなら、既にアクティブなタップダンスと同じキーか確認します(もしアクティブなものがある場合、それと)。 +異なる場合、まず、古いタップダンスを処理し、続いて新しいタップダンスを登録します。 +同じ場合、カウンタの値を増やし、タイマーをリセットします。 + +このことは、あなたは再びキーをタップするまでの時間として `TAPPING_TERM` の時間を持っていることを意味します。そのため、あなたは1つの `TAPPING_TERM` の時間内に全てのタップを行う必要はありません。これにより、キーの反応への影響を最小限に抑えながら、より長いタップ回数を可能にします。 + +次は `matrix_scan_tap_dance()` です。この関数はタップダンスキーのタイムアウトを制御します。 + +柔軟性のために、タップダンスは、キーコードの組み合わせにも、ユーザー関数にもなることができます。後者は、より高度なタップ回数の制御や、LED を点滅させたり、バックライトをいじったり、等々の制御を可能にします。これは、1つの共用体と、いくつかの賢いマクロによって成し遂げられています。 + +## 実装例 :id=examples + +### シンプルな実装例 :id=simple-example + +ここに1つの定義のための簡単な例があります。 + +1. `rules.mk` に `TAP_DANCE_ENABLE = yes` を追加します。 +2. `config.h` ファイル(`qmk_firmware/keyboards/planck/config.h` からあなたのキーマップディレクトリにコピーできます)に `#define TAPPING_TERM 200` を追加します。 +3. `keymap.c` ファイルに変数とタップダンスの定義を定義し、それからキーマップに追加します。 + +```c +// タップダンスの宣言 +enum { + TD_ESC_CAPS, +}; + +// タップダンスの定義 +qk_tap_dance_action_t tap_dance_actions[] = { + // 1回タップすると Escape キー、2回タップすると Caps Lock。 + [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), +}; + +// キーコードの代わりにタップダンスキーを追加します +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + // ... + TD(TD_ESC_CAPS) + // ... +}; +``` + +### 複雑な実装例 :id=complex-examples + +このセクションでは、いくつかの複雑なタップダンスの例を詳しく説明します。 +例で使われている全ての列挙型はこのように宣言します。 + +```c +// 全ての例のための列挙型定義 +enum { + CT_SE, + CT_CLN, + CT_EGG, + CT_FLSH, + X_TAP_DANCE +}; +``` +#### 例1: 1回タップすると `:` を送信し、2回タップすると `;` を送信する :id=example-1 + +```c +void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + register_code16(KC_COLN); + } else { + register_code(KC_SCLN); + } +} + +void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + unregister_code16(KC_COLN); + } else { + unregister_code(KC_SCLN); + } +} + +// 全てのタップダンス関数はここに定義します。ここでは1つだけ示します。 +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), +}; +``` + +#### 例2: 100回タップした後に "Safety Dance!" を送信します :id=example-2 + +```c +void dance_egg(qk_tap_dance_state_t *state, void *user_data) { + if (state->count >= 100) { + SEND_STRING("Safety dance!"); + reset_tap_dance(state); + } +} + +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), +}; +``` + +#### 例3: 1つずつ LED を点灯させてから消灯する :id=example-3 + +```c +// タップする毎に、LED を右から左に点灯します。 +// 4回目のタップで、右から左に消灯します。 +void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { + switch (state->count) { + case 1: + ergodox_right_led_3_on(); + break; + case 2: + ergodox_right_led_2_on(); + break; + case 3: + ergodox_right_led_1_on(); + break; + case 4: + ergodox_right_led_3_off(); + wait_ms(50); + ergodox_right_led_2_off(); + wait_ms(50); + ergodox_right_led_1_off(); + } +} + +// 4回目のタップで、キーボードをフラッシュ状態にセットします。 +void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) { + if (state->count >= 4) { + reset_keyboard(); + } +} + +// もしフラッシュ状態にならない場合、LED を左から右に消灯します。 +void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { + ergodox_right_led_1_off(); + wait_ms(50); + ergodox_right_led_2_off(); + wait_ms(50); + ergodox_right_led_3_off(); +} + +// 全てのタップダンス関数を一緒に表示しています。この例3は "CT_FLASH" です。 +qk_tap_dance_action_t tap_dance_actions[] = { + [CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT), + [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), + [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), + [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset) +}; +``` + +#### 例4: クアッドファンクションのタップダンス :id=example-4 + +[DanielGGordon](https://github.com/danielggordon) によるもの + +キーを押す回数と、キーを押し続けるかタップするかによって、1つのキーに4つ(またはそれ以上)の機能を持たせることができるようになります。 + +以下に例をあげます: +* 1回タップ = `x` を送信 +* 押し続ける = `Control` を送信 +* 2回タップ = `Escape` を送信 +* 2回タップして押し続ける = `Alt` を送信 + +'クアッドファンクションのタップダンス' を利用できるようにするには、いくつかのものが必要になります。 + +`keymap.c` ファイルの先頭、つまりキーマップの前に、以下のコードを追加します。 + +```c +typedef struct { + bool is_press_action; + uint8_t state; +} tap; + +enum { + SINGLE_TAP = 1, + SINGLE_HOLD, + DOUBLE_TAP, + DOUBLE_HOLD, + DOUBLE_SINGLE_TAP, // シングルタップを2回送信 + TRIPLE_TAP, + TRIPLE_HOLD +}; + +// タップダンスの列挙型 +enum { + X_CTL, + SOME_OTHER_DANCE +}; + +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// xタップダンスのための関数。キーマップで利用できるようにするため、ここに置きます。 +void x_finished(qk_tap_dance_state_t *state, void *user_data); +void x_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +次に、`keymap.c` ファイルの末尾に、次のコードを追加する必要があります。 + +```c +/* 実行されるタップダンスの種類に対応する整数を返します。 + * + * タップダンスの状態を判別する方法: 割り込みと押下。 + * + * 割り込み: + * タップダンスの状態が「割り込み」の場合、他のキーがタップ時間中に押されたことを意味します。 + * これは通常、キーを「タップ」しようとしていることを示します。 + * + * 押下: + * キーがまだ押されているかどうか。この値が true の場合、タップ時間が終了したことを意味しますが、 + * キーはまだ押されたままです。これは通常、キーが「ホールド」されていることを意味します。 + * + * タップダンスに関して、qmk ソフトウェアで現在不可能なことの1つは、"permissive hold" 機能を + * 模倣することです。 + * 一般に、高度なタップダンスは一般的に入力される文字で使われた場合にうまく機能しません。 + * 例えば "A" の場合。タップダンスは文字の入力中に入力しない文字以外のキーで使うのが最適です。 + * + * 高度なタップダンスを配置するのに適した場所: + * z、q、x、j、k、v、b、ファンクションキー、home/end、コンマ、セミコロン + * + * タップダンスキーの「最適な配置場所」の基準: + * 文章中で頻繁に入力するキーでないこと + * ダブルタップに頻繁に使われるキーでないこと。例えば、'tab' はターミナルやウェブフォームで + * しばしばダブルタップされます。そのため、タップダンスでは 'tab' は良い選択ではありません。 + * 一般的な単語で2回続けて使われる文字でないこと。例えば 'pepper' 中の 'p'。もしタップダンス機能が + * 文字 'p' に存在する場合、'pepper' という単語は入力するのが非常にいらだたしいものになるでしょう。 + * + * 3つ目の点については、'DOUBLE_SINGLE_TAP' が存在しますが、これは完全にはテストされていません + * + */ +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (state->interrupted || !state->pressed) return SINGLE_TAP; + // キーは割り込まれていませんが、まだ押し続けられています。'HOLD' を送信することを意味します。 + else return SINGLE_HOLD; + } else if (state->count == 2) { + // DOUBLE_SINGLE_TAP は "pepper" と入力することと、'pp' と入力したときに実際に + // ダブルタップしたい場合とを区別するためのものです。 + // この戻り値の推奨されるユースケースは、'ダブルタップ' 動作やマクロではなく、 + // そのキーの2つのキー入力を送信したい場合です。 + if (state->interrupted) return DOUBLE_SINGLE_TAP; + else if (state->pressed) return DOUBLE_HOLD; + else return DOUBLE_TAP; + } + + // 誰も同じ文字を3回入力しようとしていないと仮定します(少なくとも高速には)。 + // タップダンスキーが 'KC_W' で、"www." と高速に入力したい場合、ここに例外を追加して + // 'TRIPLE_SINGLE_TAP' を返し、'DOUBLE_SINGLE_TAP' のようにその列挙型を定義する必要があります。 + if (state->count == 3) { + if (state->interrupted || !state->pressed) return TRIPLE_TAP; + else return TRIPLE_HOLD; + } else return 8; // マジックナンバー。いつかこのメソッドはより多くの押下に対して機能するよう拡張されるでしょう +} + +//'x' タップダンスの 'tap' のインスタンスを生成します。 +static tap xtap_state = { + .is_press_action = true, + .state = 0 +}; + +void x_finished(qk_tap_dance_state_t *state, void *user_data) { + xtap_state.state = cur_dance(state); + switch (xtap_state.state) { + case SINGLE_TAP: register_code(KC_X); break; + case SINGLE_HOLD: register_code(KC_LCTRL); break; + case DOUBLE_TAP: register_code(KC_ESC); break; + case DOUBLE_HOLD: register_code(KC_LALT); break; + // 最後の case は高速入力用です。キーが `f` であると仮定します: + // 例えば、`buffer` という単語を入力するとき、`Esc` ではなく `ff` を送信するようにします。 + // 高速入力時に `ff` と入力するには、次の文字は `TAPPING_TERM` 以内に入力する必要があります。 + // `TAPPING_TERM` はデフォルトでは 200ms です。 + case DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X); + } +} + +void x_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (xtap_state.state) { + case SINGLE_TAP: unregister_code(KC_X); break; + case SINGLE_HOLD: unregister_code(KC_LCTRL); break; + case DOUBLE_TAP: unregister_code(KC_ESC); break; + case DOUBLE_HOLD: unregister_code(KC_LALT); + case DOUBLE_SINGLE_TAP: unregister_code(KC_X); + } + xtap_state.state = 0; +} + +qk_tap_dance_action_t tap_dance_actions[] = { + [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset) +}; +``` + +これで、キーマップのどこでも簡単に `TD(X_CTL)` マクロが使えます。 + +もし、この機能をユーザスペースで実現したい場合、 [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) がユーザスペースでどのように実装しているか確認してください。 + +> この設定の "hold" は、タップダンスのタイムアウト(`ACTION_TAP_DANCE_FN_ADVANCED_TIME` 参照)の **後** に起こります。即座に "hold" を得るためには、条件から `state->interrupted` の確認を除きます。結果として、複数回のタップのための時間をより多く持つことで快適な長いタップの期限を使うことができ、そして、"hold" のために長く待たないようにすることができます(2倍の `TAPPING TERM` で開始してみてください)。 + +#### 例5: タップダンスを高度なモッドタップとレイヤータップキーに使う :id=example-5 + +タップダンスは、タップされたコードが基本的なキーコード以外の場合に、 `MT()` と `LT()` マクロをエミュレートするのに利用できます。これは、通常 `Shift` を必要とする '(' や '{' のようなキーや、`Control + X` のように他の修飾されたキーコードをタップされたキーコードとして送信することに役立ちます。 + +あなたのレイヤーとカスタムキーコードの下に、以下のコードを追加します。 + +```c +// タップダンスのキーコード +enum td_keycodes { + ALT_LP // 例: 押していると `LALT`、タップすると `(`。それぞれのタップダンスの追加のキーコードを追加します +}; + +// 必要な数のタップダンス状態を含むタイプを定義します +typedef enum { + SINGLE_TAP, + SINGLE_HOLD, + DOUBLE_SINGLE_TAP +} td_state_t; + +// タップダンスの状態の型のグローバルインスタンスを作ります +static td_state_t td_state; + +// タップダンス関数を宣言します: + +// 現在のタップダンスの状態を特定するための関数 +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// それぞれのタップダンスキーコードに適用する `finished` と `reset` 関数 +void altlp_finished(qk_tap_dance_state_t *state, void *user_data); +void altlp_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +キーレイアウト(`LAYOUT`)の下に、タップダンスの関数を定義します。 + +```c +// 返却するタップダンス状態を特定します +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (state->interrupted || !state->pressed) return SINGLE_TAP; + else return SINGLE_HOLD; + } + + if (state->count == 2) return DOUBLE_SINGLE_TAP; + else return 3; // 上記で返却する最大の状態の値より大きい任意の数 +} + +// 定義する各タップダンスキーコードのとりうる状態を制御します: + +void altlp_finished(qk_tap_dance_state_t *state, void *user_data) { + td_state = cur_dance(state); + switch (td_state) { + case SINGLE_TAP: + register_code16(KC_LPRN); + break; + case SINGLE_HOLD: + register_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_on(_MY_LAYER)` を使います + break; + case DOUBLE_SINGLE_TAP: // タップ時間内に2つの括弧 `((` の入れ子を可能にします + tap_code16(KC_LPRN); + register_code16(KC_LPRN); + } +} + +void altlp_reset(qk_tap_dance_state_t *state, void *user_data) { + switch (td_state) { + case SINGLE_TAP: + unregister_code16(KC_LPRN); + break; + case SINGLE_HOLD: + unregister_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_off(_MY_LAYER)` を使います + break; + case DOUBLE_SINGLE_TAP: + unregister_code16(KC_LPRN); + } +} + +// 各タップダンスキーコードの `ACTION_TAP_DANCE_FN_ADVANCED()` を定義し、`finished` と `reset` 関数を渡します +qk_tap_dance_action_t tap_dance_actions[] = { + [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) +}; +``` + +それぞれのタップダンスキーコードをキーマップに含めるときは、`TD()` マクロでキーコードをラップします。例: `TD(ALT_LP)` + +#### 例6: タップダンスを一時的なレイヤー切り替えとレイヤートグルキーに使う :id=example-6 + +タップダンスは、MO(layer) と TG(layer) 機能を模倣することにも使用できます。この例では、1回タップすると `KC_QUOT` 、1回押してそのまま押し続けたら `MO(_MY_LAYER)` 、2回タップしたときは `TG(_MY_LAYER)` として機能するキーを設定します。 + +最初のステップは、あなたの `keymap.c` ファイルの最初のあたりに以下のコードを追加します。 + +```c +typedef struct { + bool is_press_action; + uint8_t state; +} tap; + +// 必要な数のタップダンス状態のタイプを定義します +enum { + SINGLE_TAP = 1, + SINGLE_HOLD, + DOUBLE_TAP +}; + +enum { + QUOT_LAYR, // カスタムタップダンスキー。他のタップダンスキーはこの列挙型に追加します +}; + +// タップダンスキーで使われる関数を宣言します + +// 全てのタップダンスに関連する関数 +uint8_t cur_dance(qk_tap_dance_state_t *state); + +// 個別のタップダンスに関連する関数 +void ql_finished(qk_tap_dance_state_t *state, void *user_data); +void ql_reset(qk_tap_dance_state_t *state, void *user_data); +``` + +あなたの `keymap.c` ファイルの最後の方に以下のコードを追加します。 + +```c +// 現在のタップダンスの状態を決定します +uint8_t cur_dance(qk_tap_dance_state_t *state) { + if (state->count == 1) { + if (!state->pressed) return SINGLE_TAP; + else return SINGLE_HOLD; + } else if (state->count == 2) return DOUBLE_TAP; + else return 8; +} + +// この例のタップダンスキーに関連付けられた "tap" 構造体を初期化します +static tap ql_tap_state = { + .is_press_action = true, + .state = 0 +}; + +// タップダンスキーの動作をコントロールする関数 +void ql_finished(qk_tap_dance_state_t *state, void *user_data) { + ql_tap_state.state = cur_dance(state); + switch (ql_tap_state.state) { + case SINGLE_TAP: + tap_code(KC_QUOT); + break; + case SINGLE_HOLD: + layer_on(_MY_LAYER); + break; + case DOUBLE_TAP: + // レイヤーが既にセットされているか確認します + if (layer_state_is(_MY_LAYER)) { + // レイヤーが既にセットされていたら、オフにします。 + layer_off(_MY_LAYER); + } else { + // レイヤーがセットされていなかったら、オンにします。 + layer_on(_MY_LAYER); + } + break; + } +} + +void ql_reset(qk_tap_dance_state_t *state, void *user_data) { + // キーを押し続けていて今離したら、レイヤーをオフに切り替えます。 + if (ql_tap_state.state == SINGLE_HOLD) { + layer_off(_MY_LAYER); + } + ql_tap_state.state = 0; +} + +// タップダンスキーを機能に関連付けます +qk_tap_dance_action_t tap_dance_actions[] = { + [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275) +}; +``` + +上記のコードは、前の例で使われたコードに似ています。注意する1つのポイントは、必要に応じてレイヤーを切り替えられるように、どのレイヤーがアクティブになっているかいつでも確認できる必要があることです。これを実現するために、引数で与えられた `layer` がアクティブなら `true` を返す `layer_state_is(layer)` を使います。 + +`cur_dance()` と `ql_tap_state` の使い方は、上の例と似ています。 + +`ql_finished` 関数における `case:SINGLE_TAP` は、上の例と似ています。`SINGLE_HOLD` の case では、`ql_reset()` と連動してタップダンスキーを押している間 `_MY_LAYER` に切り替わり、キーを離した時に `_MY_LAYER` から離れます。これは、`MO(_MY_LAYER)` に似ています。`DOUBLE_TAP` の case では、`_MY_LAYER` がアクティブレイヤーかどうかを確認することによって動きます。そして、その結果に基づいてレイヤーのオン・オフをトグルします。これは `TG(_MY_LAYER)` に似ています。 + +`tap_dance_actions[]` は、上の例に似ています。 `ACTION_TAP_DANCE_FN_ADVANCED()` の代わりに `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` を使ったことに注意してください。 +この理由は、私は、非タップダンスキーを使うにあたり `TAPPING_TERM` が短い(175ミリ秒以内)方が好きなのですが、タップダンスのアクションを確実に完了させるには短すぎるとわかったからです——そのため、ここでは時間を275ミリ秒に増やしています。 + +最後に、このタップダンスキーを動かすため、忘れずに `TD(QUOT_LAYR)` を `keymaps[]` に加えてください。 diff --git a/ja/feature_terminal.md b/ja/feature_terminal.md new file mode 100644 index 00000000000..8e125ecee0c --- /dev/null +++ b/ja/feature_terminal.md @@ -0,0 +1,112 @@ +# ターミナル + + + +> この機能は現在のところ*巨大*であり、おそらく大量のメモリを搭載したキーボード、または楽しみのためにのみ配置する必要があります。 + +ターミナル機能はテキストエディタを介してキーストロークで通信するように設計されたコマンドラインのようなインタフェースです。エディタで自動インデント機能をオフにすることは有益です。 + +有効にするには、以下を `rules.mk` または `Makefile` に貼り付けます: + + TERMINAL_ENABLE = yes + +そして、オンまたはオフにするために、`TERM_ON` および `TERM_OFF` キーコードを使います。 + +有効な場合、`> ` プロンプトが現れ、ここでコマンドやバックスペース(オーディオが有効な場合は、先頭に到達するとベルが鳴ります)を入力することができ、エンターを入力するとコマンドを送信します。矢印キーは現在のところ無効なため、混乱することはありません。マウスでカーソルを移動することはお勧めしません。 + +`#define TERMINAL_HELP` は、このページでは実際には必要のない他の出力ヘルパーを有効にします。 + +"上矢印" および "下矢印" により、過去に入力した5つのコマンドを順に切り替えることができます。 + +## 今後のアイデア + +* キーボード/ユーザ拡張可能なコマンド +* より小さなフットプリント +* 矢印キーのサポート +* コマンド履歴 - 完了 +* SD カードのサポート +* バッファディスプレイのための LCD サポート +* キーコード -> 名称の対応表 +* レイヤー状態 +* *アナログ/デジタル ポートの読み込み/書き込み* +* RGB モード関連機能 +* マクロ定義 +* EEPROM の読み込み/書き込み +* オーディオ制御 + +## 現在のコマンド + +### `about` + +現在の QMK のバージョンとビルドした日の出力: + +``` +> about +QMK Firmware + v0.5.115-7-g80ed73-dirty + Built: 2017-08-29-20:24:44 +``` + + +### `print-buffer` + +最後に入力した5つのコマンドの出力 + +``` +> print-buffer +0. print-buffer +1. help +2. about +3. keymap 0 +4. help +5. flush-buffer +``` + +### `flush-buffer` + +コマンドバッファをクリア +``` +> flush-buffer +Buffer cleared! +``` + + +### `help` + + +利用可能なコマンドの出力: + +``` +> help +commands available: + about help keycode keymap exit print-buffer flush-buffer +``` + +### `keycode ` + +特定のレイヤー、行および列のキーコード値の出力: + +``` +> keycode 0 1 0 +0x29 (41) +``` + +### `keymap ` + +特定のレイヤーの全てのキーマップの出力 + +``` +> keymap 0 +0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a, +0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034, +0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028, +0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f, +> +``` + +### `exit` + +ターミナルの終了 - `TERM_OFF` と同じ。 diff --git a/ja/feature_thermal_printer.md b/ja/feature_thermal_printer.md new file mode 100644 index 00000000000..508123bd64e --- /dev/null +++ b/ja/feature_thermal_printer.md @@ -0,0 +1,15 @@ +# 感熱式プリンタ + + + + + +## 感熱式プリンタのキーコード + +| キー | 説明 | +|-----------|----------------------------------------| +| `PRINT_ON` | ユーザが入力した全ての印刷を開始 | +| `PRINT_OFF` | ユーザが入力した全ての印刷を停止 | diff --git a/ja/feature_userspace.md b/ja/feature_userspace.md new file mode 100644 index 00000000000..d0d46f63f87 --- /dev/null +++ b/ja/feature_userspace.md @@ -0,0 +1,260 @@ +# ユーザスペース: キーマップ間でのコードの共有 + + + +似たキーマップを複数のキーボードで使う場合、それらの間でコードを共有できるという利点が得られることがあります。`users/`に以下の構造でキーマップ(理想的には GitHub のユーザ名、``)と同じ名前の独自のフォルダを作成します: + +* `/users//` (パスに自動的に追加されます) + * `readme.md` (オプション、推奨) + * `rules.mk` (自動的に含まれます) + * `config.h` (自動的に含まれます) + * `.h` (オプション) + * `.c` (オプション) + * `cool_rgb_stuff.c` (オプション) + * `cool_rgb_stuff.h` (オプション) + + +以下のように、`` という名前のキーマップをビルドする時のみ、これが全て起きます: + + make planck: + +例えば、 + + make planck:jack + +は、`/users/jack/rules.mk` に加えて、パスに `/users/jack/` フォルダを含めます。 + +!> この `name` は必要に応じて[上書き](#override-default-userspace)することができます。 + +## `Rules.mk` + +`rules.mk` は自動的に処理される2つファイルのうちの1つです。これにより、コンパイル時に追加のソースファイル( `.c` など)を追加できます。 + +追加されるデフォルトのソースファイルとして `.c` を使うことを強くお勧めします。それを追加するために、以下のように `rules.mk` に SRC を追加する必要があります: + + SRC += .c + +追加のファイルも同じ方法で追加できます - ただし、``.c/.h という名前のファイルを最初に用意することをお勧めします。 + +ビルド時に `/users//rules.mk` ファイルはキーマップの `rules.mk` の_後_でインクルードされます。これにより、キーボードによっては利用できないことのある個々の QMK 機能を利用する機能をユーザスペース `rules.mk` に持つことができます。 + +例えば、RGB ライトをサポートする全てのキーボード間で RGB 制御機能を共有する場合、RGBLIGHT 機能が有効であればサポートを追加することができます: +```make +ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) + # ここにファンシーな rgb 関数のソースを含める + SRC += cool_rgb_stuff.c +endif +``` + +別のやり方として、キーマップの `rules.mk` で `define RGB_ENABLE` と定義し、以下のようにユーザスペースの `rules.mk` で変数をチェックすることができます: +```make +ifdef RGB_ENABLE + # ここにファンシーな rgb 関数のソースを含める + SRC += cool_rgb_stuff.c +endif +``` + +### デフォルトのユーザスペースの上書き :id=override-default-userspace + +デフォルトでは、使用されるユーザスペース名はキーマップ名と同じです。状況によってはこれは望ましくありません。例えば、[レイアウト](ja/feature_layouts.md)機能を使う場合、異なるキーマップに同じ名前 (例えば、ANSI および ISO) を使うことができません。レイアウトに `mylayout-ansi` や `mylayout-iso` という名前を付け、以下の行をレイアウトの `rules.mk` に追加します: + +``` +USER_NAME := mylayout +``` + +これは、基板上に物理的に異なる機能を備えた、複数の異なるキーボード(RGBライトを備えたキーボード、オーディオを備えたキーボード、LEDの数が異なる、コントローラ上の異なるPINに接続されているなど)がある場合にも役立ちます。 + +## 設定オプション (`config.h`) + +さらに、ここにある `config.h` はキーマップフォルダ内の同名のファイルと同じように処理されます。これは `.h` ファイルとは別個に処理されます。 + +この理由は、`.h` は (`#define TAPPING_TERM 100` などのような)設定を追加する時には追加されず、`config.h` ファイル内の `` ファイルを含めるとコンパイルの問題を引き起こすからです。 + +!>`config.h` は[設定オプション](ja/config_options.md)のために使い、`.h` ファイルはユーザあるいは(レイヤーあるいはキーコードのための enum のような)キーマップ固有の設定のために使うべきです + + +## Readme (`readme.md`) + +作者情報 (あなたの名前、GitHub ユーザ名、eメール)およびオプションで[GPL 互換のライセンス](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses)を含めてください。 + +以下をテンプレートとして使うことができます: +``` +Copyright @ + +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 . +``` + +年、名前、eメールおよび GitHub ユーザ名をあなたの情報に置き換えます。 + +さらに、コードを他の人に共有したい場合、ここはコードを文章化するのに適した場所です。 + +## 特定のキーマップをサポートする全てのキーボードをビルドする + +1つのコマンドで全てのキーマップのビルドを確認したいですか?以下で実行することができます: + + make all: + +例えば、 + + make all:jack + +これは、[_プルリクエスト_](https://github.com/qmk/qmk_firmware/pulls) を準備する時に全てが正常にコンパイルされることを確認したい場合に最適です。 + +## 例 + +簡単な例については、[`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/_example) を調べてください。 +より複雑な例については、[`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna) のユーザスペースを調べてください。 + + +### カスタマイズされた関数 :id=customized-functions + +QMK には、[`_quantum`、`_kb` および `_user` バージョン](ja/custom_quantum_functions.md#a-word-on-core-vs-keyboards-vs-keymap)を持つ使用可能な[関数](custom_quantum_functions.md)が山ほどあります。 ほとんどの場合、これらの関数のユーザバージョンを使う必要があります。しかし問題はそれらをユーザスペースで使う場合、キーマップで使うことができるバージョンが無いことです。 + +しかし、実際にはキーマップバージョンのサポートを追加し、ユーザスペースとキーマップの両方で使うことができます。 + + +例えば、`layer_state_set_user()` 関数を見てみましょう。全てのキーボードで [Tri Layer State](ja/ref_functions.md#olkb-tri-layers) 機能を有効にしながら、`keymap.c` ファイルで Tri Layer 機能を保持することができます。 + +`` ファイル内で、以下を追加する必要があります: +```c +__attribute__ ((weak)) +layer_state_t layer_state_set_keymap (layer_state_t state) { + return state; +} + +layer_state_t layer_state_set_user (layer_state_t state) { + state = update_tri_layer_state(state, 2, 3, 5); + return layer_state_set_keymap (state); +} +``` +`__attribute__ ((weak))` 部分は、コンパイラにこれが `keymap.c` 内のバージョンに置き換えられるプレースホルダ関数であることを伝えます。そうすれば、`keymap.c` に追加する必要はありませんが、追加しても関数が同じ名前を持つため競合することはありません。 + +ここでの `_keymap` 部分は重要では無く、`_quantum`、`_kb` あるいは `_user` は既に使われているため、それら以外のものである必要があります。`layer_state_set_mine`、`layer_state_set_fn` などを使うことができます。 + +[`users/drashna`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna) 内の [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) でこのリストと他の一般的な関数を見つけることができます。 + +### カスタム機能 + +ユーザスペース機能は膨大な数のキーボードをサポートすることができるため、特定の機能は有効にしたいが、他のキーボードでは有効にしたくないかもしれません。そして実際に自分のユーザスペースで有効あるいは無効にすることができる「機能」を作成することができます。 + +例えば、(スペースを節約するために)特定のキーボードでのみたくさんのマクロを利用したい場合、それらを `#ifdef MACROS_ENABLED` して「見えないように」してから、キーボードごとに有効にすることができます。これを行うには、以下を rules.mk に追加します。 +```make +ifeq ($(strip $(MACROS_ENABLED)), yes) + OPT_DEFS += -DMACROS_ENABLED +endif +``` +`OPT_DEFS` 設定は `MACROS_ENABLED` がキーボード用に定義されるようにし(名前の前に `-D` があることに注意してください)、c/h ファイルで状態をチェックするために `#ifdef MACROS_ENABLED` を使うことができ、それに基づいてそのコードを処理します。 + +次にキーマップの `rules.mk` に `MACROS_ENABLED = yes` を追加し、ユーザスペースでこの機能とコードを有効にします。 + +そして `process_record_user` 関数の中で、以下のようなことを行います: +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { +#ifdef MACROS_ENABLED + case MACRO1: + if (!record->event.pressed) { + SEND_STRING("This is macro 1!"); + } + break; + case MACRO2: + if (!record->event.pressed) { + SEND_STRING("This is macro 2!"); + } + break; +#endif + } + return true; +} +``` + + +### 結合マクロ + +全てのキーマップについてユーザスペースにマクロやそのほかの関数を統合したい場合は、そうすることができます。これは上記の[カスタマイズ関数](#customized-functions)の例に基づいています。これは異なるキーボード間で共有される大量のマクロを維持し、キーボード固有のマクロも可能です。 + +最初に、全ての `keymap.c` ファイルを調べ、代わりに `process_record_user` を `process_record_keymap` に置き換えます。この方法では、これらのキーボードでキーボード固有のコードを使用でき、カスタムの "global" キーコードも使うことができます。また、`SAFE_RANGE` を `NEW_SAFE_RANGE` に置き換えて、キーコードが重複しないようにすることもできます。 + +次に、全ての keymap.c ファイルに `#include ` を追加します。これにより、各キーマップでそれらを再定義することなく新しいキーコードを使うことができます。 + +それが完了したら、必要なキーコードの定義を `.h` ファイルに設定します。例えば: +```c +#pragma once + +#include "quantum.h" +#include "action.h" +#include "version.h" + +// 全てを定義 +enum custom_keycodes { + KC_MAKE = SAFE_RANGE, + NEW_SAFE_RANGE // キーマップ固有のコードについては "NEW_SAFE_RANGE" を使用 +}; +``` + +ここで、`.c` ファイルを作成し、この内容をそれに追加します: + +```c +#include ".h" + +__attribute__ ((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_MAKE: // ファームウェアをコンパイルし、キーボードのブートローダに基づく書き込みコマンドを追加します + if (!record->event.pressed) { + uint8_t temp_mod = get_mods(); + uint8_t temp_osm = get_oneshot_mods(); + clear_mods(); clear_oneshot_mods(); + SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP); + #ifndef FLASH_BOOTLOADER + if ((temp_mod | temp_osm) & MOD_MASK_SHIFT) + #endif + { + SEND_STRING(":flash"); + } + if ((temp_mod | temp_osm) & MOD_MASK_CTRL) { + SEND_STRING(" -j8 --output-sync"); + } + tap_code(KC_ENT); + set_mods(temp_mod); + } + break; + + } + return process_record_keymap(keycode, record); +} +``` + +(マクロパッドのような) Shift ボタンを持たないキーボードについては、ブートローダオプションを常に含める方法が必要です。これを行うには、以下をユーザスペースフォルダ内の `rules.mk` に追加します: + +```make +ifeq ($(strip $(FLASH_BOOTLOADER)), yes) + OPT_DEFS += -DFLASH_BOOTLOADER +endif +``` + +これは任意のキーマップで使うことができる新しい `KC_MAKE` キーコードを追加します。そして、このキーコードは、`make :` を出力するため、頻繁なコンパイルを簡単にします。そして、これは現在のキーボードの情報を出力するため、全てのキーボードとキーマップで動作します。そのため毎回これを入力する必要はありません。 + +また、Shift を押したままにすると書き込みの対象 (`:flash`) をコマンドに追加します。Control を押したままにすると、複数のファイルを一度に処理することでコンパイル時間を短縮する幾つかのコマンドを追加します。 + +そして Shift キーが無いキーボード、あるいは常に書き込みを試したいキーボードについては、キーマップの `rules.mk` に `FLASH_BOOTLOADER = yes` を追加することができます。 + +?> これはブートローダの設定に基づいて正しいユーティリティを使って新しくコンパイルされたファームウェアを自動的に書き込むはずです (あるいはデフォルトで HEX ファイルを生成するだけ)。ただし、これは全てのシステムで動作するわけではないことに注意してください。はっきり言うと、AVRDUDE は WSL では動作しません。そして、これは BootloadHID あるいは mdloader をサポートしません。 diff --git a/ja/feature_velocikey.md b/ja/feature_velocikey.md new file mode 100644 index 00000000000..f9b6e73bd48 --- /dev/null +++ b/ja/feature_velocikey.md @@ -0,0 +1,35 @@ +# Velocikey + + + +Velocikey は入力の速度を使って(レインボー渦巻効果のような)ライト効果の速度を制御できる機能です。速く入力すればするほどライトが速くなります! + +## 使用法 +Velocikey を使うためには、2つのステップがあります。最初に、キーボードをコンパイルする時に、`rules.mk` に `VELOCIKEY_ENABLE=yes` を設定する必要があります。例えば: + +``` +BOOTMAGIC_ENABLE = no +MOUSEKEY_ENABLE = no +STENO_ENABLE = no +EXTRAKEY_ENABLE = yes +VELOCIKEY_ENABLE = yes +``` + +次に、キーボードの使用中に、VLK_TOG キーコードを使って Velocikey を有効にする必要もあります。これは機能をオンおよびオフにします。 + +以下の全てのライト効果が、Velocikey を有効にすることで制御されます: +- RGB 明滅動作 +- RGB レインボームード +- RGB レインボー渦巻 +- RGB スネーク +- RGB ナイト + +LED 明滅動作の効果のサポートは計画されていますがまだ利用できません。 + +Velocikey が有効になっている限り、現在オンになっている RGB ライトの他の全ての速度設定に関係なく、速度が制御されます。 + +## 設定 +Velocikey は現在のところキーボード設定を介したどのような設定もサポートしません。速度の増加あるいは減少率などを調整したい場合は、`velocikey.c` を編集し、そこで値を調整して、好みの速度を実現する必要があります。 diff --git a/ja/feature_wpm.md b/ja/feature_wpm.md new file mode 100644 index 00000000000..3cb5e58fcb0 --- /dev/null +++ b/ja/feature_wpm.md @@ -0,0 +1,24 @@ +# Word Per Minute (WPM) の計算 + + + +WPM 機能は、キーストローク間の時間から1分あたりの平均(移動平均)単語数を計算し、様々な用途で利用できるようにします。 + +`rules.mk` に以下を追加することで WPM システムを有効にします: + + WPM_ENABLE = yes + +ソフトシリアルを使っている分割キーボードについては、計算された WPM スコアがマスター側とスレーブ側で利用可能です。 + +## 公開関数 + +`uint8_t get_current_wpm(void);` +この関数は符号なし整数で現在の WPM を返します。 + + +## WPM 計算のためのカスタマイズ化されたキー + +デフォルトでは、WPM スコアは文字、空白、およびいくつかの句読点のみを含みます。WPM の計算に含むとみなす文字セットを変更したい場合は、`wpm_keycode_user(uint16_t keycode)` を実装し、計算に含めたい文字について true を返し、計算しない特定のキーコードに false を返すようにします。 diff --git a/ja/flashing.md b/ja/flashing.md new file mode 100644 index 00000000000..b2c0dcd868f --- /dev/null +++ b/ja/flashing.md @@ -0,0 +1,247 @@ +# 書き込みの手順とブートローダ情報 + + + +キーボードが使用するブートローダにはかなり多くの種類があり、ほぼ全てが異なる書き込みの方法を使います。幸いなことに、[QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) のようなプロジェクトは、あまり深く考える必要無しに様々なタイプと互換性を持つことを目指していますが、この文章では様々なタイプのブートローダとそれらを書き込むために利用可能な方法について説明します。 + +`rules.mk` の `BOOTLOADER` 変数で選択されたブートローダがある場合、QMK は .hex ファイルがデバイスに書き込むのに適切なサイズかどうかを自動的に計算し、合計サイズをバイト単位で(最大値とともに)出力します。 + +## DFU + +Atmel の DFU ブートローダはデフォルトで全ての atmega32u4 チップに搭載されており、PCB (旧 OLKB キーボード、Clueboard) に独自の IC を持つ多くのキーボードで使われています。一部のキーボードは、LUFA の DFU ブートローダ(または QMK のフォーク) (新しい OLKB キーボード)を使う場合もあり、そのハードウェアに固有の追加機能が追加されます。 + +DFU ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください(オプションとして代わりに `lufa-dfu` や `qmk-dfu` が使えます): + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = atmel-dfu +``` + +互換性のあるフラッシャ: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) +* QMK の [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` (推奨のコマンドライン) + +書き込み手順: + +1. `RESET` キーコードを押すか、RESET ボタンをタップします(または RST を GND にショートします)。 +2. OS がデバイスを検知するのを待ちます。 +3. メモリを消去します(自動的に実行されるかもしれません) +4. .hex ファイルを書き込みます +5. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + +あるいは: + + make ::dfu + +### QMK DFU + +QMK には LUFA DFU ブートローダのフォークがあり、ブートローダを終了してアプリケーションに戻る時に単純なマトリックススキャンを行うことができます。また、何かが起きた時に、LED を点滅したり、スピーカーでカチカチ音をたてたりします。これらの機能を有効にするには、`config.h` で以下のブロックを有効にします (ブートローダを終了するキーは、ここで定義された INPUT と OUTPUT に接続する必要があります): + + #define QMK_ESC_OUTPUT F1 // 通常 COL + #define QMK_ESC_INPUT D5 // 通常 ROW + #define QMK_LED E6 + #define QMK_SPEAKER C6 + +製造元と製品名は `config.h` から自動的に取得され、製品に「Bootloader」が追加されます。 + +このブートローダを生成するには、`bootloader` ターゲット、例えば `make planck/rev4:default:bootloader` を使います。 + +実稼働対応の .hex ファイル(アプリケーションおよびブートローダを含む)を生成するには、`production` ターゲット、例えば `make planck/rev4:default:production` を使います。 + +### DFU コマンド + +ファームウェアを DFU デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 + +* `:dfu` - これが通常のオプションで、DFU デバイスが使用可能になるまで待機したのちファームウェアを書き込みます。5秒ごとに、DFU デバイスが存在するかチェックしています。 +* `:dfu-ee` - 通常の hex ファイルの代わりに `eep` ファイルを書き込みます。これを使用するのはまれです。 +* `:dfu-split-left` - デフォルトオプション (`:dfu`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM ファイルも書き込まれます。_これは、Elite C ベースの分割キーボードに最適です。_ +* `:dfu-split-right` - デフォルトオプション (`:dfu`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM ファイルも書き込まれます。_これは、Elite C ベースの分割キーボードに最適です。_ + +## Caterina + +Arduino ボードとそのクローンは [Caterina ブートローダ](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina) (Pro Micro またはそのクローンで構築されたキーボード)を使用し、avr109 プロトコルを使って仮想シリアルを介して通信します。[A-Star](https://www.pololu.com/docs/0J61/9) のようなブートローダは Caterina に基づいています。 + +Caterina ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = caterina +``` + +互換性のあるフラッシャ: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) +* avr109 を使った [avrdude](http://www.nongnu.org/avrdude/) / `:avrdude` (推奨のコマンドライン) +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +書き込み手順: + +1. `RESET` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます) +2. OS がデバイスを検知するのを待ちます。 +3. .hex ファイルを書き込みます +4. デバイスが自動的にリセットされるのを待ちます + +あるいは + + make ::avrdude + + +### Caterina コマンド + +ファームウェアを DFU デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 + +* `:avrdude` - これが通常のオプションで、Caterina デバイスが(新しい COM ポートを検出して)使用可能になるまで待機し、ファームウェアを書き込みます。 +* `:avrdude-loop` - これは `:avrdude` と同じコマンドを実行します。ただし書き込みが終了すると再び Caterina デバイスの書き込み待ちに戻ります。これは何台ものデバイスへ書き込むのに便利です。_Ctrl+C を押して、手動でこの繰り返しを終了させる必要があります。_ +* `:avrdude-split-left` - デフォルトオプション (`:avrdude`) と同様に通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM ファイルも書き込まれます。_これは、Pro Micro ベースの分割キーボードに最適です。_ +* `:avrdude-split-right` - デフォルトオプション (`:avrdude`) と同様に通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM ファイルも書き込まれます。_これは、Pro Micro ベースの分割キーボードに最適です。_ + + + +## Halfkay + +Halfkay は PJRC によって開発された超スリムなプロトコルであり、HID を使用し、全ての Teensys (つまり 2.0)に搭載されています。 + +Halfkay ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = halfkay +``` + +互換性のあるフラッシャ: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) +* [Teensy ローダー](https://www.pjrc.com/teensy/loader.html) +* [Teensy ローダーコマンドライン](https://www.pjrc.com/teensy/loader_cli.html) (推奨のコマンドライン) + +書き込み手順: + +1. `RESET` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます) +2. OS がデバイスを検知するのを待ちます。 +3. .hex ファイルを書き込みます +4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + +## USBasploader + +USBasploader は matrixstorm によって開発されたブートローダです。V-USB を実行する ATmega328P のような非 USB AVR チップで使われます。 + +USBasploader ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = USBasp +``` + +互換性のあるフラッシャ: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) +* `usbasp` プログラマを使った [avrdude](http://www.nongnu.org/avrdude/) +* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) + +書き込み手順: + +1. `RESET` キーコードを押すか、RST を GND にすばやくショートしながら、ブートピンを GND にショートしたままにします。 +2. OS がデバイスを検知するのを待ちます。 +3. .hex ファイルを書き込みます +4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + +## BootloadHID + +BootloadHID は AVR マイクロコントローラ用の USB ブートローダです。アップローダーツールは Windows でカーネルレベルのドライバを必要としないため、DLL をインストールせずに実行することができます。 + +bootloadHID ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: + +```make +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = bootloadHID +``` + +互換性のあるフラッシャ: + +* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) (推奨の Windows GUI) +* [bootloadhid コマンドライン](https://www.obdev.at/products/vusb/bootloadhid.html) / QMK の `:BootloadHID` (推奨のコマンドライン) + +書き込み手順: + +1. 以下のいずれかの方法を使ってブートローダに入ります: + * `RESET` キーコードをタップします (全てのデバイスでは動作しないかもしれません) + * キーボードを接続しながらソルトキーを押し続けます (通常はキーボードの readme に書かれています) +2. OS がデバイスを検知するのを待ちます。 +3. .hex ファイルを書き込みます +4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + +あるいは: + + make ::bootloadHID + +## STM32 + +全ての STM32 チップには、変更も削除もできない工場出荷時のブートローダがプリロードされています。一部の STM32 チップには USB プログラミングが付属していないブートローダがありますが(例えば STM32F103)、プロセスは同じです。 + +現時点では、STM32 の `rules.mk` には、`BOOTLOADER` 変数は不要です。 + +互換性のあるフラッシャ: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) +* [dfu-util](https://github.com/Stefan-Schmidt/dfu-util) / `:dfu-util` (推奨のコマンドライン) + +書き込み手順: + +1. 以下のいずれかの方法を使ってブートローダに入ります: + * `RESET` キーコードをタップします (STM32F042 デバイスでは動作しないかもしれません) + * リセット回路が存在する場合、RESET ボタンをタップします + * それ以外の場合は、(BOOT0 ボタンあるいはブリッジ経由で)BOOT0 を VCC にブリッジし、(REEST ボタンあるいはブリッジ経由で)RESET を GND にショートし、BOOT0 ブリッジを放す必要があります。 +2. OS がデバイスを検知するのを待ちます。 +3. .bin ファイルを書き込みます + * DFU 署名に関する警告が表示されます; 無視してください +4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + * コマンドラインからビルドする場合(例えば、`make planck/rev6:default:dfu-util`)、`rules.mk` の中で `:leave` が `DFU_ARGS` 変数に渡されるようにしてください (例えば、`DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave`)。そうすれば、書き込みの後でデバイスがリセットされます + +### STM32 コマンド + +ファームウェアを STM32 デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 + +* `:dfu-util` - STM32 デバイスに書き込むためのデフォルトコマンドで、STM32 ブートローダデバイスが見つかるまで待機します。 +* `:dfu-util-split-left` - デフォルトのオプション (`:dfu-util`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM の設定も行われます。 +* `:dfu-util-split-right` - デフォルトのオプション (`:dfu-util`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM の設定も行われます。 +* `:st-link-cli` - dfu-util ではなく、ST-LINK の CLI ユーティリティを介してファームウェアを書き込めます。 +* `:st-flash` - dfu-util ではなく、[STLink Tools](https://github.com/stlink-org/stlink) の `st-flash` ユーティリティを介してファームウェアを書き込めます。 diff --git a/ja/flashing_bootloadhid.md b/ja/flashing_bootloadhid.md new file mode 100644 index 00000000000..ddcd776c240 --- /dev/null +++ b/ja/flashing_bootloadhid.md @@ -0,0 +1,75 @@ +# BootloadHID の書き込み手順とブートローダの情報 + + + +ps2avr(GB) キーボードは ATmega32A マイクロコントローラを使い、異なるブートローダを使います。それは通常の QMK の方法を使って書き込むことができません。 + +一般的な書き込みシーケンス: + +1. 以下のいずれかの方法を使ってブートローダに入ります: + * `RESET` キーコードをタップします (全てのデバイスでは動作しないかもしれません) + * ソルトキーを押し続けながらキーボードを接続します (通常はキーボードの readme に書かれています) +2. OS がデバイスを検知するのを待ちます。 +3. .hex ファイルを書き込みます +4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) + +## bootloadHID の書き込みターゲット + +?> [こちら](ja/newbs_getting_started.md)で詳しく説明されている QMK インストールスクリプトを使うと、必要な bootloadHID ツールが自動的にインストールされます。 + +コマンドライン経由で書き込むには、以下のコマンドを実行してターゲット `:bootloadHID` を使います: + + make ::bootloadHID + +## GUI 書き込み + +### Windows +1. [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) をダウンロードします。 +2. キーボードをリセットします。 +3. 設定された VendorID が `16c0` で、ProductID が `05df` であることを確認します +4. `Find Device` ボタンを押し、キーボードが見つかることを確認します。 +5. `Open .hex File` ボタンを押し、作成した `.hex` ファイルを見つけます。 +6. `Flash Device` ボタンを押し、処理が完了するまで待ちます。 + +## コマンドライン書き込み + +1. キーボードをリセットします。 +2. `bootloadHID -r` に続けて `.hex` ファイルへのパスを入力し、キーボードに書き込みます。 + +### Windows 手動インストール +MSYS2の場合: +1. https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz から BootloadHID ファームウェアパッケージをダウンロードします。 +2. 互換性のあるツール、例えば 7-Zip を使って内容を抽出します。 +3. 解凍された書庫から MSYS2 インストール先、通常 `C:\msys64\usr\bin` に `commandline/bootloadHID.exe` をコピーして、MSYS パスに追加します。 + +ネイティブの Windows 書き込みの場合、MSYS2 環境の外部で `bootloadHID.exe` を使うことができます。 + +### Linux 手動インストール +1. libusb development の依存関係をインストールします: + ```bash + # これは OS に依存します - Debian については以下で動作します +sudo apt-get install libusb-dev + ``` +2. BootloadHID ファームウェアパッケージをダウンロードします: + ``` + wget https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -O - | tar -xz -C /tmp + ``` +3. bootloadHID 実行可能ファイルをビルドします: + ``` + cd /tmp/bootloadHID.2012-12-08/commandline/ +make +sudo cp bootloadHID /usr/local/bin + ``` + +### MacOS 手動インストール +1. 以下を入力して Homebrew をインストールします: + ``` + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + ``` +2. 以下のパッケージをインストールします: + ``` + brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb + ``` diff --git a/ja/getting_started_docker.md b/ja/getting_started_docker.md new file mode 100644 index 00000000000..6498d727b4d --- /dev/null +++ b/ja/getting_started_docker.md @@ -0,0 +1,52 @@ +# Docker クイックスタート + + + +このプロジェクトは、プライマリオペレーティングシステムに大きな変更を加えることなくキーボードの新しいファームウェアを非常に簡単に構築することができる Docker ワークフローを含みます。これは、あなたがプロジェクトをクローンしビルドを実行した時に、他の人とまったく同じ環境と QMK ビルド基盤を持つことも保証します。これにより、人々はあなたが遭遇した問題の解決をより簡単に行えるようになります。 + +## 必要事項 + +主な前提条件は動作する `docker` がインストールされていることです。 +* [Docker CE](https://docs.docker.com/install/#supported-platforms) + +## 使い方 + +(サブモジュールを含む) QMK のレポジトリのローカルコピーを取得する: + +```bash +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +キーマップをビルドするために以下のコマンドを実行します: +```bash +util/docker_build.sh : +# 例えば: util/docker_build.sh planck/rev6:default +``` + +これは目的のキーボード/キーマップをコンパイルし、結果として書き込み用に `.hex` あるいは `.bin` ファイルを QMK ディレクトリの中に残します。`:keymap` が省略された場合は全てのキーマップが使われます。パラメータの形式は、`make` を使ってビルドする時と同じであることに注意してください。 + +`target` を指定して Docker から直接キーボードをビルドし、_かつ_書き込むためのサポートもあります。 + +```bash +util/docker_build.sh keyboard:keymap:target +# 例えば: util/docker_build.sh planck/rev6:default:flash +``` + +スクリプトをパラメータ無しで開始することもできます。この場合、1つずつビルドパラメータを入力するように求められます。これが使いやすいと思うかもしれません: + +```bash +util/docker_build.sh +# パラメータを入力として読み込みます (空白にすると全てのキーボード/キーマップ) +``` + +## FAQ + +### なぜ Windows/macOS 上で書き込めないのですか? + +Windows と macOS では、実行するために [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) が必要です。これはセットアップが面倒なので、お勧めではありません: 代わりに [QMK Toolbox](https://github.com/qmk/qmk_toolbox) を使ってください。 + +!> Docker for Windows は[Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) を有効にする必要があります。これは、Windows 7、Windows 8 および **Windows 10 Home** のような Hyper-V を搭載していない Windows のバージョンでは機能しないことを意味します。 diff --git a/ja/getting_started_github.md b/ja/getting_started_github.md new file mode 100644 index 00000000000..a768f8926a9 --- /dev/null +++ b/ja/getting_started_github.md @@ -0,0 +1,70 @@ +# QMK で GitHub を使う方法 + + + +GitHub は慣れていない人には少し注意が必要です - このガイドは、QMK におけるフォーク、クローン、プルリクエストのサブミットの各ステップについて説明します。 + +?> このガイドでは、あなたがコマンドラインでの実行にある程度慣れており、システムに git がインストールされていることを前提にしています。 + +[QMK GitHub ページ](https://github.com/qmk/qmk_firmware)を開くと、右上に "Fork" というボタンが見えます: + +![GitHub でのフォーク](http://i.imgur.com/8Toomz4.jpg) + +あなたが組織の一員である場合は、どのアカウントにフォークするかを選択する必要があります。ほとんどの場合、あなたの個人のアカウントにフォークしたいでしょう。フォークが完了したら(しばらく時間が掛かる場合があります)、"Clone or Download" ボタンをクリックします: + +![GitHub からダウンロード](http://i.imgur.com/N1NYcSz.jpg) + +必ず "HTTPS" を選択し、リンクを選択してコピーします: + +![HTTPS リンク](http://i.imgur.com/eGO0ohO.jpg) + +ここから、`git clone --recurse-submodules ` をコマンドラインに入力し、リンクを貼り付けます: + +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +ローカルマシンに QMK のフォークができるので、キーマップの追加、コンパイル、キーボードへの書き込みができます。変更に満足したら、以下のようにそれらをフォークへ追加、コミットおよびプッシュすることができます: + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +あなたの変更は今では GitHub 上のフォークにあります - フォーク (`https://github.com//qmk_firmware`)に戻ると、"New Pull Request" ボタンをクリックすることで新しいプルリクエストを作成することができます: + +![New Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +ここでは、コミットした内容を正確に確認することができます - 全て良いように見える場合は、"Create Pull Request" をクリックすることで最終的に承認することができます: + +![Create Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +サブミットの後で、私たちはあなたの変更について話し、変更を依頼し、最終的にそれを受け入れるでしょう!QMK に貢献してくれてありがとう :) diff --git a/ja/getting_started_introduction.md b/ja/getting_started_introduction.md new file mode 100644 index 00000000000..a55391e0a1c --- /dev/null +++ b/ja/getting_started_introduction.md @@ -0,0 +1,65 @@ +# はじめに + + + +このページでは、QMK プロジェクトで作業するために知っておくべき基本的な情報について説明しようと思います。Unix シェルの操作に精通していることを前提としていますが、C について、または make を使ったコンパイルについて精通しているとは想定していません。 + +## 基本的な QMK の構造 + +QMK は [Jun Wako](https://github.com/tmk) の [tmk_keyboard](https://github.com/tmk/tmk_keyboard) プロジェクトのフォークです。変更された元の TMK コードは、`tmk_core` フォルダで見つけることができます。プロジェクトへの QMK の追加は、`quantum` フォルダで見つけることができます。キーボードプロジェクトは `handwired` および `keyboard` フォルダで見つけることができます。 + +### ユーザスペースの構造 + +`users` フォルダ内は各ユーザのためのディレクトリです。これはユーザがキーボード間で使うかもしれないコードを置くためのフォルダです。詳細は[ユーザスペース機能](ja/feature_userspace.md) のドキュメントを見てください。 + +### キーボードプロジェクトの構造 + +`keyboards` フォルダ、そのサブフォルダ `handwired`、ベンダと製品のサブディレクトリ (例えば、`clueboard`) の中には、各キーボードプロジェクトのためのディレクトリ (例えば `qmk_firmware/keyboards/clueboard/2x1800`) があります。その中には、以下の構造があります: + +* `keymaps/`: ビルドできる様々なキーマップ +* `rules.mk`: デフォルトの "make" オプションを設定するファイル。このファイルを直接編集しないでください。代わりにキーマップ固有の `rules.mk` を使ってください。 +* `config.h`: デフォルトのコンパイル時のオプションを設定するファイル。このファイルを直接編集しないでください。代わりにキーマップ固有の `config.h` を使ってください。 +* `info.json`: QMK Configurator のためのレイアウトの設定に使われるファイル。詳細は [Configurator サポート](ja/reference_configurator_support.md)を見てください。 +* `readme.md`: キーボードの簡単な概要 +* `.h`: このファイルは、キーボードのスイッチマトリックスに対してキーボードレイアウトが定義されるファイルです。 +* `.c`: このファイルには、キーボードのためのカスタムコードがあります。 + +プロジェクトの構造についての詳細は、[QMK キーボードガイドライン](ja/hardware_keyboard_guidelines.md)を見てください。 + +### キーマップ構造 + +全てのキーマップフォルダには、以下のファイルがあります。`keymap.c` だけが必須で、残りのファイルが見つからない場合は、デフォルトのオプションが選択されます。 + +* `config.h`: キーマップを設定するためのオプション +* `keymap.c`: 全てのキーマップコード。必須 +* `rules.mk`: 有効になっている QMK の機能 +* `readme.md`: キーマップの説明。他の人が使う方法および機能の説明。imgur のようなサービスに画像をアップロードしてください。 + +# `config.h` ファイル + +3つの `config.h` の場所が考えられます: + +* キーボード (`/keyboards//config.h`) +* ユーザスペース (`/users//config.h`) +* キーマップ (`/keyboards//keymaps//config.h`) + +ビルドシステムは自動的に上の順に config ファイルを取得します。前の `config.h` で設定された設定を上書きしたい場合は、変更したい設定の準備のために最初に定型コードを置く必要があります。 + +``` +#pragma once +``` + +次に、前の `config.h` ファイルの設定を上書きするために、設定を `#undef` し再び `#define` する必要があります。 + +定型コードと設定は、以下のようになります: + +``` +#pragma once + +// ここに上書きします! +#undef MY_SETTING +#define MY_SETTING 4 +``` diff --git a/ja/getting_started_make_guide.md b/ja/getting_started_make_guide.md new file mode 100644 index 00000000000..08005877e73 --- /dev/null +++ b/ja/getting_started_make_guide.md @@ -0,0 +1,149 @@ +# より詳細な `make` 手順 + + + +`make` コマンドの完全な構文は `::` です: + +* `` はキーボードのパスです。例えば、`planck` + * 全てのキーボードをコンパイルするには `all` を使います。 + * リビジョンを選択してコンパイルするためのパスを指定します。例えば `planck/rev4` あるいは `planck/rev3` + * キーボードにフォルダが無い場合は、省略することができます + * デフォルトのフォルダをコンパイルする場合は、省略することができます +* `` はキーマップの名前です。例えば、`algernon` + * 全てのキーマップをコンパイルするには `all` を使います。 +* `` の詳細は以下で説明します。 + +`` は以下を意味します +* target が指定されない場合は、以下の `all` と同じです +* `all` は指定されたキーボード/リビジョン/キーマップの可能な全ての組み合わせのコンパイルを行います。例えば、`make planck/rev4:default` は1つの .hex を生成しますが、`make planck/rev4:all` は planck で利用可能な全てのキーマップについて hex を生成します。 +* `flash`、`dfu`、`teensy`、`avrdude`、`dfu-util` または `bootloadHID` はファームウェアをコンパイルし、キーボードにアップロードします。コンパイルが失敗すると、何もアップロードされません。使用するプログラマはキーボードに依存します。ほとんどのキーボードでは `dfu` ですが、ChibiOS キーボードについては `dfu-util` 、標準的な Teensy については `teensy` を使います。キーボードに使うコマンドを見つけるには、キーボード固有の readme をチェックしてください。 +* **注意**: 一部のオペレーティングシステムではこれらのコマンドが機能するためには root アクセスが必要です。その場合、例えば `sudo make planck/rev4:default:flash` を実行する必要があります。 +* `clean` は、全てをゼロからビルドするためにビルド出力フォルダを掃除します。説明できない問題がある場合は、通常のコンパイルの前にこれを実行してください。 + +make コマンドの最後、つまり target の後に追加のオプションを追加することもできます + +* `make COLOR=false` - カラー出力をオフ +* `make SILENT=true` - エラー/警告以外の出力をオフ +* `make VERBOSE=true` - 全ての gcc のものを出力 (デバッグする必要が無い限り面白くありません) +* `make EXTRAFLAGS=-E` - コンパイルせずにコードを前処理 (#define コマンドをデバッグしようとする場合に便利) + +make コマンド自体にもいくつかの追加オプションがあります。詳細は `make --help` を入力してください。最も有用なのはおそらく `-jx` です。これは複数の CPU を使ってコンパイルしたいことを指定し、`x` は使用したい CPU の数を表します。設定すると、特に多くのキーボード/キーマップをコンパイルしている場合は、コンパイル時間を大幅に短縮することができます。通常は、コンパイル中に他の作業を行うための余裕をもたせるために、持っている CPU の数より1つ少ない値に設定します。全てのオペレーティングシステムと make バージョンがオプションをサポートしているわけではないことに注意してください。 + +コマンドの例を幾つか示します + +* `make all:all` は、全てをビルドします (全てのキーボードフォルダ、全てのキーマップ)。`root` から単に `make` を実行すると、これを実行します。 +* `make ergodox_infinity:algernon:clean` は、Ergodox Infinity キーボードのビルド出力を掃除します。 +* `make planck/rev4:default:flash COLOR=false` カラー出力なしでキーマップをビルドしアップロードします。 + +## `rules.mk` オプション + +無効にするにはこれらの変数を `no` に設定します。有効にするには `yes` に設定します。 + +`BOOTMAGIC_ENABLE` + +これにより、1つのキーとソルトキー(デフォルトではスペース)を押し続けることで、電力が失われても持続する様々な EEPROM 設定へアクセスできます。誤って設定が変更されることが多く、デバッグするのが難しい混乱した結果を生成するため、これを無効にしておくことをお勧めします。ヘルプセッションで発生する、より一般的な問題の1つです。 + +`MOUSEKEY_ENABLE` + +これにより、キーコード/カスタム関数を介して、カーソルの動きとクリックを制御することができます。 + +`EXTRAKEY_ENABLE` + +これにより、システムとオーディオ制御キーコードを使うことができます。 + +`CONSOLE_ENABLE` + +これにより、[`hid_listen`](https://www.pjrc.com/teensy/hid_listen.html) を使って読むことができるメッセージを出力することができます。 + +デフォルトで、全てのデバッグ( *dprint* ) 出力 ( *print*、*xprintf* )、およびユーザ出力 ( *uprint* ) メッセージが有効になります。これにより、フラッシュメモリの大部分が消費され、キーボードの .hex ファイルが大きすぎてプログラムできなくなるかもしれません。 + +デバッグメッセージ( *dprint* ) を無効にし、.hex ファイルのサイズを小さくするには、`config.h` に `#define NO_DEBUG` を含めます。 + +出力メッセージ( *print*、*xprintf* )とユーザ出力( *uprint* ) を無効にし、.hex のファイルサイズを小さくするには、`config.h` に `#define NO_PRINT` を含めます。 + +出力メッセージ ( *print*、*xprintf* ) を無効にし、ユーザメッセージ ( *uprint* )を**そのままにする**には、`config.h` に `#define USER_PRINT` を含めます(この場合は、`#define NO_PRINT` も含めないでください)。 + +テキストを見るには、`hid_listen` を開き、出力メッセージを見るのを楽しんでください。 + +**注意:** キーマップコード以外の *uprint* メッセージを含めないでください。QMK システムフレームワーク内で使うべきではありません。さもないと、他の人の .hex ファイルが肥大化します。 + +`COMMAND_ENABLE` + +これはマジックコマンドを有効にし、通常はデフォルトのマジックキーの組み合わせ `LSHIFT+RSHIFT+KEY` で起動されます。マジックコマンドは、デバッグメッセージ (`MAGIC+D`) の有効化や NKRO の一時的な切り替え (`MAGIC+N`) を含みます。 + +`SLEEP_LED_ENABLE` + +コンピュータがスリープの間に LED がブレスできるようにします。ここでは Timer1 が使われます。この機能は大部分が未使用でテストされておらず、更新もしくは抽象化が必要です。 + +`NKRO_ENABLE` + +これにより、キーボードはホスト OS に最大 248 個のキーが同時に押されていることを伝えることができます (NKRO 無しのデフォルトは 6 です)。NKRO は、`NKRO_ENABLE` が設定されていたとしても、デフォルトではオフです。config.h に `#define FORCE_NKRO` を追加するか、`MAGIC_TOGGLE_NKRO` をキーにバインドしてキーを押すことで、NKRO を強制することができます。 + +`BACKLIGHT_ENABLE` + +これはスイッチ内の LED のバックライトを有効にします。`config.h` 内に以下を入れることでバックライトピンを指定することができます: + + #define BACKLIGHT_PIN B7 + +`MIDI_ENABLE` + +キーボードで MIDI の送受信を有効にします。MIDI 送信モードに入るためにキーコード `MI_ON` を使うことができ、オフにするために `MI_OFF` を使うことができます。これはほとんどテストされていない機能ですが、詳細については `quantum/quantum.c` ファイルで見つけることができます。 + +`UNICODE_ENABLE` + +これによりキーマップで `UC()` を使って Unicode 文字を送信することができます。`0x7FFF` までのコードポイントがサポートされます。これはほとんどの現代言語の文字と記号を対象にしますが、絵文字は対象外です。 + +`UNICODEMAP_ENABLE` + +これによりキーマップで `X()` を使って Unicode 文字を送信することができます。キーマップファイル内にマッピングテーブルを保持する必要があります。可能な全てのコードポイント( `0x10FFFF` まで)がサポートされます。 + +`UCIS_ENABLE` + +これにより、送信したい文字に対応するニーモニックを入力することで Unicode 文字を送信することができます。キーマップファイル内にマッピングテーブルを保持する必要があります。可能な全てのコードポイント( `0x10FFFF` まで)がサポートされます。 + +詳細と制限については、[Unicode ページ](ja/feature_unicode.md) を見てください。 + +`AUDIO_ENABLE` + +C6 ピン(抽象化が必要)でオーディオ出力できます。詳細は[オーディオページ](ja/feature_audio.md)を見てください。 + +`FAUXCLICKY_ENABLE` + +クリック音のあるスイッチをエミュレートするためにブザーを使います。Cherry社製の青軸スイッチの安っぽい模倣です。デフォルトでは、`AUDIO_ENABLE` と同じように C6 ピンを使います。 + +`VARIABLE_TRACE` + +これを使って変数の値の変更をデバッグします。詳細についてはユニットテストのページの[変数のトレース](ja/unit_testing.md#tracing-variables)のセクションを見てください。 + +`API_SYSEX_ENABLE` + +これにより Quantum SYSEX API を使って文字列を送信することができます (どこに?) + +`KEY_LOCK_ENABLE` + +これは [キーロック](ja/feature_key_lock.md) を有効にします。 + +`SPLIT_KEYBOARD` + +分割キーボード (let's split や bakingpy's boards のようなデュアル MCU) のサポートを有効にし、quantum/split_common にある全ての必要なファイルをインクルードします + +`SPLIT_TRANSPORT` + +ARM ベースの分割キーボード用の標準分割通信ドライバはまだ無いため、これらのために `SPLIT_TRANSPORT = custom` を使わなければなりません。カスタムの実装が使われるようにすることで、標準の分割キーボード通信コード(AVR 固有)が含まれないようにします。 + +`CUSTOM_MATRIX` + +デフォルトのマトリックス走査ルーチンを独自のコードで置き換えます。詳細については、[カスタムマトリックスページ](ja/custom_matrix.md) を見てください。 + +`DEBOUNCE_TYPE` + +デフォルトのキーデバウンスルーチンを別のものに置き換えます。`custom` の場合、独自の実装を提供する必要があります。 + +## キーマップごとに Makefile オプションをカスタマイズ + +あなたのキーマップディレクトリに `rules.mk` というファイルがある場合、そのファイルで設定した全てのオプションは、あなたのキーボードの他の `rules.mk` オプションよりも優先されます。 + +あなたのキーボードの `rules.mk` に `BACKLIGHT_ENABLE = yes` があるとします。あなたの特定のキーボードでバックライトが無いようにするには、`rules.mk` というファイルを作成し、`BACKLIGHT_ENABLE = no` を指定します。 diff --git a/ja/getting_started_vagrant.md b/ja/getting_started_vagrant.md new file mode 100644 index 00000000000..58eca5c0a30 --- /dev/null +++ b/ja/getting_started_vagrant.md @@ -0,0 +1,61 @@ +# Vagrant クイックスタート + + + +このプロジェクトは、プライマリオペレーティングシステムに大きな変更を加えることなくキーボードの新しいファームウェアを非常に簡単に構築することができる `Vagrantfile` を含みます。これは、あなたがプロジェクトをクローンしビルドを実行した時に、ビルドのために Vagrantfile を使っている他のユーザと全く同じ環境を持つことも保証します。これにより、人々はあなたが遭遇した問題の解決をより簡単に行えるようになります。 + +## 必要事項 + +このリポジトリ内の `Vagrantfile` を使うには、[Vagrant](http://www.vagrantup.com/) およびサポートされるプロバイダがインストールされている必要があります: + +* [VirtualBox](https://www.virtualbox.org/) (バージョン 5.0.12 以降) + * 'Vagrant を使うために最もアクセスしやすいプラットフォーム' として販売 +* [VMware Workstation](https://www.vmware.com/products/workstation) および [Vagrant VMware プラグイン](http://www.vagrantup.com/vmware) + * (有料) VMware プラグインには、ライセンスされた VMware Workstation/Fusion のコピーが必要です。 +* [Docker](https://www.docker.com/) + +Vagrant 以外に、適切なプロバイダがインストールされ、その後におそらくコンピュータを再起動すると、このプロジェクトをチェックアウトしたフォルダ内の任意の場所で 'vagrant up' を単純に実行することができ、このプロジェクトをビルドするのに必要な全てのツールが含まれる環境(仮想マシンあるいはコンテナ)が開始されます。Vagrant をうまく始めるためのヒントの投稿がありますが、それ以外に、以下のビルドドキュメントを参照することもできます。 + +## ファームウェアの書き込み + +ファームウェアを書き込む"簡単"な方法は、ホスト OS からツールを使うことです: + +* [QMK Toolbox](https://github.com/qmk/qmk_toolbox) (推奨) +* [Teensy ローダー](https://www.pjrc.com/teensy/loader.html) + +コマンドラインでプログラムしたい場合は、Vagranfile の ['modifyvm'] 行のコメントを解除して Linux への USB パススルーを有効にし、dfu-util/dfu-programmer のようなコマンドラインツールを使ってプログラムすることができます。あるいは Teensy CLI バージョンをインストールすることができます。 + +## Vagrantfile の概要 +開発環境は QMK Docker イメージ、`qmkfm/base_container` を実行するように設定されています。これはシステム間の予測可能性が保証されるだけでなく、CI 環境もミラーされます。 + +## FAQ + +### Virtualbox で問題が発生するのはなぜですか? +Virtualbox 5 の特定のバージョンはこの Vagrantfile のボックスにインストールされている Virtualbox の拡張機能と互換性が無いようです。/vagrant のマウントで問題が発生した場合は、Virtualbox のバージョンを少なくとも 5.0.12 にアップグレードしてください。**または、以下のコマンドを実行してみることができます:** + +```console +vagrant plugin install vagrant-vbguest +``` + +### 既存の環境を削除するにはどうすればいいですか? +あなたの環境での作業が完了しましたか?このプロジェクトをチェックアウトしたフォルダの中のどこからでも、以下を実行してください: + +```console +vagrant destroy +``` + +### Docker を直接使いたい場合はどうしますか? +仮想マシン無しで Vagrant のワークフローを活用したいですか?Vagrantfile は仮想マシンの実行をバイパスし、コンテナを直接実行するように設定されています。Docker を強制的に使うように環境を立ち上げる場合は、以下を実行してください: +```console +vagrant up --provider=docker +``` + +### Docker コンテナではなく仮想マシンにアクセスするにはどうすればいいですか? +以下を実行して、公式の QMK ビルダーイメージから直接起動する `vagrant` ユーザをバイパスするようにします: + +```console +vagrant ssh -c 'sudo -i' +``` diff --git a/ja/hardware_avr.md b/ja/hardware_avr.md new file mode 100644 index 00000000000..1308c3fdaf5 --- /dev/null +++ b/ja/hardware_avr.md @@ -0,0 +1,188 @@ +# AVR マイコンを使ったキーボード + + + +このページでは QMK における AVR マイコンのサポートについて説明します。AVR マイコンには、Atmel 社製の atmega32u4、atmega32u2、at90usb1286 やその他のマイコンを含みます。AVR マイコンは、簡単に動かせるよう設計された8ビットの MCU です。キーボードでよく使用される AVR マイコンには USB 機能や大きなキーボードマトリックスのためのたくさんの GPIO を搭載しています。これらは、現在、キーボードで使われる最も一般的な MCU です。 + +まだ読んでない場合は、[キーボードガイドライン](ja/hardware_keyboard_guidelines.md) を読んで、キーボードを QMK にどのように適合させるかを把握する必要があります。 + +## AVR を使用したキーボードを QMK に追加する + +QMK には AVR を使ったキーボードでの作業を簡略化するための機能が多数あります。大体のキーボードでは1行もコードを書く必要がありません。まずはじめに、`util/new_keyboard.sh` スクリプトを実行します。 + +``` +$ ./util/new_keyboard.sh +Generating a new QMK keyboard directory + +Keyboard Name: mycoolkb +Keyboard Type [avr]: +Your Name [John Smith]: + +Copying base template files... done +Copying avr template files... done +Renaming keyboard files... done +Replacing %KEYBOARD% with mycoolkb... done +Replacing %YOUR_NAME% with John Smith... done + +Created a new keyboard called mycoolkb. + +To start working on things, cd into keyboards/mycoolkb, +or open the directory in your favourite text editor. +``` + +これにより、新しいキーボードをサポートするために必要なすべてのファイルが作成され、デフォルト値で設定が入力されます。あとはあなたのキーボード用にカスタマイズするだけです。 + +## `readme.md` + +このファイルではキーボードに関する説明を記述します。[キーボード Readme テンプレート](ja/documentation_templates.md#keyboard-readmemd-template)に従って `readme.md` を記入して下さい。`readme.md` の上部に画像を配置することをお勧めします。画像は [Imgur](http://imgur.com) のような外部サービスを利用してください。 + +## `.c` + +このファイルではキーボード上で実行される全てのカスタマイズされたロジックを記述します。多くのキーボードの場合、何も書く必要はありません。 +[機能のカスタマイズ](ja/custom_quantum_functions.md)で、カスタマイズされたロジックの記述方法を詳しく学ぶことが出来ます。 + +## `.h` + +このファイルでは、[レイアウト](ja/feature_layouts.md)を定義します。最低限、以下のような `#define LAYOUT` を記述する必要があります。 + +```c +#define LAYOUT( \ + k00, k01, k02, \ + k10, k11 \ +) { \ + { k00, k01, k02 }, \ + { k10, KC_NO, k11 }, \ +} +``` + +`LAYOUT` マクロの前半部ではキーの物理的な配置を定義します。後半部ではスイッチが接続されるマトリックスを定義します。これによってマトリックス配線の順とは異なるキーを物理的に配置できます。 + +それぞれの `k__` 変数はユニークでなければいけません。通常は `k` というフォーマットに従って記述されます。 + +物理マトリックス(後半部)では、`MATRIX_ROWS` に等しい行数が必要であり、各行には正確に `MATRIX_COLS` と等しい数の要素が含まれていなければいけません。物理キーが存在しない場合は、`KC_NO` を使用して空白を埋める事ができます。 + +## `config.h` + +`config.h` ファイルには、ハードウェアや機能の設定を記述します。このファイルで設定できるオプションは列挙しきれないほどたくさんあります。利用できるオプションの概要は[設定オプション](ja/config_options.md)を参照して下さい。 + +### ハードウェアの設定 + +`config.h` の先頭には USB に関する設定があります。これらはキーボードが OS からどのように見えるかを制御しています。変更する理由がない場合は、`VENDOR_ID` を `0xFEED` のままにしておく必要があります。`PRODUCT_ID` にはまだ使用されていない番号を選ばなければいけません。 + +`MANUFACTURER`、 `PRODUCT` をキーボードにあった設定に変更します。 + +```c +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER You +#define PRODUCT my_awesome_keyboard +``` + +?> Windows や macOS では、`MANUFACTURER` と `PRODUCT` が USBデバイスのリストに表示されます。Linux 上の `lsusb` では、代わりにデフォルトで [USB ID Repository](http://www.linux-usb.org/usb-ids.html) によって維持されているリストからこれらを取得します。`lsusb -v` を使用するとデバイスから示された値を表示します。また、接続したときのカーネルログにも表示されます。 + +### キーボードマトリックスの設定 + +`config.h` ファイルの次のセクションではキーボードのマトリックスを扱います。最初に設定するのはマトリックスのサイズです。これは通常、常にではありませんが、物理キー配置と同じ数の行・列になります。 + +```c +#define MATRIX_ROWS 2 +#define MATRIX_COLS 3 +``` + +マトリックスのサイズを定義したら、MCU のどのピンを行と列に接続するかを定義します。そのためにはピンの名前を指定するだけです。 + +```c +#define MATRIX_ROW_PINS { D0, D5 } +#define MATRIX_COL_PINS { F1, F0, B0 } +#define UNUSED_PINS +``` + + +`MATRIX_ROW_PINS` の要素の数は `MATRIX_ROWS` に定義した数と同じでなければいけません。同様に `MATRIX_COL_PINS` の要素の数も `MATRIX_COLS` と等しい必要があります。`UNUSED_PINS` は定義しなくても問題ありませんがどのピンが空いているのか記録しておきたい場合は定義できます。 + +最後にダイオードの方向を定義します。これには `COL2ROW` か `ROW2COL` を設定します。 + +```c +#define DIODE_DIRECTION COL2ROW +``` + +#### ダイレクトピンマトリックス + +各スイッチが、列と行のピンを共有する代わりに、それぞれ個別のピンとグランドに接続されているキーボードを定義するには、`DIRECT_PINS` を使用します。マッピング定義では、列と行の各スイッチのピンを左から右の順に定義します。`MATRIX_ROWS` と `MATRIX_COLS` 内のサイズに準拠する必要があり、空白を埋めるには `NO_PIN` を使用します。これによって `DIODE_DIRECTION`、`MATRIX_ROW_PINS`、`MATRIX_COL_PINS` の動作を上書きします。 + +```c +// #define MATRIX_ROW_PINS { D0, D5 } +// #define MATRIX_COL_PINS { F1, F0, B0 } +#define DIRECT_PINS { \ + { F1, E6, B0, B2, B3 }, \ + { F5, F0, B1, B7, D2 }, \ + { F6, F7, C7, D5, D3 }, \ + { B5, C6, B6, NO_PIN, NO_PIN } \ +} +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +//#define DIODE_DIRECTION +``` + +### バックライトの設定 + +QMK では GPIO ピンでのバックライト制御をサポートしています。これらの設定を選択して MCU から制御できます。詳しくは[バックライト](ja/feature_backlight.md)を参照して下さい。 + +```c +#define BACKLIGHT_PIN B7 +#define BACKLIGHT_LEVELS 3 +#define BACKLIGHT_BREATHING +#define BREATHING_PERIOD 6 +``` + +### その他の設定オプション + +`config.h` で設定・調整できる機能はたくさんあります。詳しくは[設定オプション](ja/config_options.md)を参照して下さい。 + +## `rules.mk` + +`rules.mk` ファイルを使用して、ビルドするファイルや有効にする機能をQMKへ指示します。atmega32u4 を使っている場合、これらのオプションはデフォルトのままにしておくことが出来ます。他の MCU を使用している場合はいくつかのパラメータを調整する必要があります。 + +### MCU オプション + +このオプションではビルドする CPU をビルドシステムに指示します。これらの設定を変更する場合は非常に注意して下さい。キーボードを操作不能にしてしまう可能性があります。 + +```make +MCU = atmega32u4 +F_CPU = 16000000 +ARCH = AVR8 +F_USB = $(F_CPU) +OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT +``` + +### ブートローダー + +ブートローダーは MCU に保存されているプログラムをアップグレードするための特別なセクションです。キーボードのレスキューパーティションのようなものだと考えて下さい。 + +#### Teensy Bootloader の例 + +```make +BOOTLOADER = halfkay +``` + +#### Atmel DFU Loader の例 + +```make +BOOTLOADER = atmel-dfu +``` + +#### Pro Micro Bootloader の例 + +```make +BOOTLOADER = caterina +``` + +### ビルドオプション + +`rules.mk` にはオン・オフできるたくさんの機能があります。詳細なリストと説明は[設定オプション](ja/config_options.md#feature-options)を参照して下さい。 diff --git a/ja/hardware_drivers.md b/ja/hardware_drivers.md new file mode 100644 index 00000000000..f77b48ba8e6 --- /dev/null +++ b/ja/hardware_drivers.md @@ -0,0 +1,45 @@ +# QMK ハードウェアドライバー + + + +QMK はたくさんの異なるハードウェアで使われています。最も一般的な MCU とマトリックス構成をサポートしていますが、キーボードへ他のハードウェアを追加し制御するためのドライバーもいくつか用意されています。例えば、マウスやポインティングデバイス、分割キーボード用の IO エキスパンダ、Bluetooth モジュール、LCD、OLED、TFT 液晶などがあります。 + + + +# 使用できるドライバー + +## ProMicro (AVR のみ) + +ProMicro のピンを AVR の名前ではなく、Arduino の名前で指定できます。この部分はより詳しく文書化される必要があります。もしこれを使用したい場合にコードを読んでも分からない場合、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new)を通して助けることができるかもしれません。 + +## SSD1306 OLED ドライバー + +SSD1306 ベースの OLED ディスプレイのサポート。詳しくは[OLED ドライバ](ja/feature_oled_driver.md)を参照して下さい。 + +## uGFX + +QMK 内で uGFX を使用して、キャラクタ LCD やグラフィック LCD、LED アレイ、OLED ディスプレイ、TFT 液晶や他のディスプレイを制御できます。この部分はより詳しく文書化される必要があります。もしこれを使用したい場合にコードを読んでも分からない場合、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new)を通して助けることができるかもしれません。 + +## WS2812 + +WS2811/WS2812{a,b,c} LED のサポート。 詳しくは [RGB ライト](ja/feature_rgblight.md)を参照して下さい。 + +## IS31FL3731 + +最大2つの LED ドライバーのサポート。各ドライバーは、I2C を使って個別に LED を制御する2つのチャーリープレクスマトリックスを実装しています。最大144個の単色 LED か32個の RGB LED を使用できます。ドライバーの設定方法の詳細は[RGB マトリックス](ja/feature_rgb_matrix.md)を参照して下さい。 + +## IS31FL3733 + +拡張の余地がある最大1つの LED ドライバーのサポート。各ドライバーは192個の単色 LED か64個の RGB LED を制御できます。ドライバーの設定方法の詳細は [RGB マトリックス](ja/feature_rgb_matrix.md)を参照して下さい。 + +## 24xx シリーズ 外部 I2C EEPROM + +オンチップ EEPROM の代わりに使用する I2C ベースの外部 EEPROM のサポート。ドライバーの設定方法の詳細は [EEPROM ドライバー](ja/eeprom_driver.md)を参照して下さい。 diff --git a/ja/hardware_keyboard_guidelines.md b/ja/hardware_keyboard_guidelines.md new file mode 100644 index 00000000000..2be099985d9 --- /dev/null +++ b/ja/hardware_keyboard_guidelines.md @@ -0,0 +1,222 @@ +# QMK キーボードガイドライン + + + +QMK は開始以来、コミュニティにおけるキーボードの作成や保守に貢献しているあなたのような人たちのおかげで飛躍的に成長しました。私たちが成長するにつれて、うまくやるためのいくつかのパターンを発見しました。他の人たちがあなたの苦労の恩恵を受けやすくするため、それにあわせてもらえるようお願いします。 + +## あなたのキーボード/プロジェクトの名前を決める + +キーボードの名前は全て小文字で、アルファベット、数字、アンダースコア(`_`)のみで構成されています。アンダースコア(`_`)で始めてはいけません。スラッシュ(`/`)はサブフォルダの区切り文字として使用されます。 + +`test`、`keyboard`、`all` はmakeコマンド用に予約されており、キーボードまたはサブフォルダ名として使用することは出来ません。 + +正しい例: + +* `412_64` +* `chimera_ortho` +* `clueboard/66/rev3` +* `planck` +* `v60_type_r` + +## サブフォルダ + +QMK では、まとめるためや同じキーボードのリビジョン間でコードを共有するためにサブフォルダを使用します。フォルダは最大4階層までネストできます。 + + qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4 + +サブフォルダ内に `rules.mk` ファイルが存在するとコンパイル可能なキーボードとして見なされます。QMK Configurator から使用できるようになり、`make all` でテストされます。同じメーカーのキーボードをまとめるためにフォルダを使用している場合は `rules.mk` ファイルを置いてはいけません。 + +例: + +Clueboard は、サブフォルダをまとめるためとキーボードのリビジョン管理の両方のために使用しています。 + +* [`qmk_firmware`](https://github.com/qmk/qmk_firmware/tree/master) + * [`keyboards`](https://github.com/qmk/qmk_firmware/tree/master/keyboards) + * [`clueboard`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard) ← これはまとめるためのフォルダです。 `rules.mk` ファイルはありません。 + * [`60`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/60) ← これはコンパイルできるキーボードです。`rules.mk` が存在します。 + * [`66`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66) ← これもコンパイルできるキーボードです。 デフォルトのリビジョンとして `DEFAULT_FOLDER` に `rev3` を指定しています。 + * [`rev1`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev1) ← コンパイル可能: `make clueboard/66/rev1` + * [`rev2`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev2) ← コンパイル可能: `make clueboard/66/rev2` + * [`rev3`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev3) ← コンパイル可能: `make clueboard/66/rev3` もしくは `make clueboard/66` + +## キーボードのフォルダ構成 + +キーボードは `qmk_firmware/keyboards/` 内にあり、前のセクションで説明したようにフォルダ名はキーボードの名前にする必要があります。このフォルダ内にはいくつかのファイルがあります。 + +* `readme.md` +* `info.json` +* `config.h` +* `rules.mk` +* `.c` +* `.h` + +### `readme.md` + +全てのプロジェクトにはどのようなキーボードなのか、誰が設計したか、どこで入手できるかを説明する `readme.md` ファイルが必要です。もしあれば、メーカーの Web サイトなどの詳しい情報へのリンクも含める必要があります。[キーボード readme テンプレート](ja/documentation_templates.md#keyboard-readmemd-template)を参考にして下さい。 + +### `info.json` + +このファイルは [QMK API](https://github.com/qmk/qmk_api) から使用されます。[QMK Configurator](https://config.qmk.fm/) が必要とするキーボードの情報が含まれています。ここでメタデータを設定することもできます。詳しくは [info.json 形式](ja/reference_info_json.md) を参照して下さい。 + +### `config.h` + +全てのプロジェクトには、マトリックスサイズ、製品名、USB VID/PID、説明、その他の設定などが含まれた `config.h` ファイルが必要です。一般に、このファイルを使用して常に機能するキーボードの重要な情報やデフォルトを設定します。 + +また、`config.h` ファイルはサブフォルダにも置くことができ、その読み込み順は以下の通りです。 + +* `keyboards/top_folder/config.h` + * `keyboards/top_folder/sub_1/config.h` + * `keyboards/top_folder/sub_1/sub_2/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/config.h` + * `users/a_user_folder/config.h` + * `keyboards/top_folder/keymaps/a_keymap/config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/post_config.h` + * `keyboards/top_folder/sub_1/sub_2/sub_3/post_config.h` + * `keyboards/top_folder/sub_1/sub_2/post_config.h` + * `keyboards/top_folder/sub_1/post_config.h` +* `keyboards/top_folder/post_config.h` + +`post_config.h` ファイルは、`config.h` ファイルで指定された内容に応じて、追加の後処理を行うために使用することができます。 +例えば、キーマップレベルの `config.h` ファイルで `IOS_DEVICE_ENABLE` マクロを以下のように定義すると、`post_config.h` ファイルでより詳細な設定を行うことができます。 + +* `keyboards/top_folder/keymaps/a_keymap/config.h` + ```c + #define IOS_DEVICE_ENABLE + ``` +* `keyboards/top_folder/post_config.h` + ```c + #ifndef IOS_DEVICE_ENABLE + // USB_MAX_POWER_CONSUMPTION value for this keyboard + #define USB_MAX_POWER_CONSUMPTION 400 + #else + // fix iPhone and iPad power adapter issue + // iOS device need lessthan 100 + #define USB_MAX_POWER_CONSUMPTION 100 + #endif + + #ifdef RGBLIGHT_ENABLE + #ifndef IOS_DEVICE_ENABLE + #define RGBLIGHT_LIMIT_VAL 200 + #define RGBLIGHT_VAL_STEP 17 + #else + #define RGBLIGHT_LIMIT_VAL 35 + #define RGBLIGHT_VAL_STEP 4 + #endif + #ifndef RGBLIGHT_HUE_STEP + #define RGBLIGHT_HUE_STEP 10 + #endif + #ifndef RGBLIGHT_SAT_STEP + #define RGBLIGHT_SAT_STEP 17 + #endif + #endif + ``` + +?> 上記の例のように `post_config.h` でオプションを定義する場合、キーボードやユーザレベルの `config.h` で同じオプションを定義してはいけません。 + +### `rules.mk` + +このファイルが存在するということは、フォルダがキーボードであり、`make` コマンドで使用できることを意味します。ここでキーボードのビルド環境を構築し、デフォルトの機能を設定します。 + +`rules.mk` ファイルはサブフォルダにも置くことができ、その読み込み順は以下の通りです。 + +* `keyboards/top_folder/rules.mk` + * `keyboards/top_folder/sub_1/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/sub_3/rules.mk` + * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/rules.mk` + * `keyboards/top_folder/keymaps/a_keymap/rules.mk` + * `users/a_user_folder/rules.mk` +* `common_features.mk` + +`rules.mk` ファイルに書かれた多くの設定は `common_features.mk` によって解釈され、必要なソースファイルやコンパイラのオプションが設定されます。 + +?> 詳しくは `build_keyboard.mk` と `common_features.mk` を見てください。 + +### `` + +ここではキーボードのカスタマイズされたコードを記述します。通常、初期化してキーボードのハードウェアを制御するコードを記述します。キーボードが LED やスピーカー、その他付属ハードウェアのないキーマトリックスのみで構成されている場合は空にできます。 + +通常、以下の関数がこのファイルで定義されます。 + +* `void matrix_init_kb(void)` +* `void matrix_scan_kb(void)` +* `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* `void led_set_kb(uint8_t usb_led)` + +### `` + +このファイルはキーボードのマトリックスを定義するために使用されます。配列をキーボードの物理的なスイッチマトリックスに変換する C マクロを最低限1つ定義する必要があります。複数のレイアウトでキーボードを構築出来る場合は、追加のマクロを定義しなければいけません。 + +レイアウトが1つしかない場合は、このマクロは `LAYOUT` とします。 + +複数のレイアウトを定義する場合、物理的に構成することが出来なくとも、マトリックス上で全てのスイッチ位置をサポートする `LAYOUT_all` という名前の基本となるレイアウトが必要です。これは `default` キーマップで使用すべきマクロです。次に、他のレイアウトマクロを使用する `default_` といった追加のキーマップを用意します。これによって、他の人が定義されたレイアウトを使いやすくなります。 + +レイアウトマクロの名前は全て小文字で、先頭の `LAYOUT` だけ大文字です。 + +例として、ANSI と ISO をサポートする 60% PCB がある場合、以下のようにレイアウトとキーマップを定義出来ます。 + +| レイアウト名 | キーマップ名 | 説明 | +|-------------|-------------|-------------| +| LAYOUT_all | default | ISO と ANSI のどちらもサポートしたレイアウト | +| LAYOUT_ansi | default_ansi | ANSI レイアウト | +| LAYOUT_iso | default_iso | ISO レイアウト | + +## 画像/ハードウェアのファイル + +リポジトリのサイズを小さく保つために、いくつかの例外を除いて、どの形式のバイナリファイルも受け入れないようになりました。外部の場所(など)でホストして、`readme.md` でリンクすることをおすすめします。 + +ハードウェアのファイル(プレートやケース、PCB など)は [qmk.fm リポジトリ](https://github.com/qmk/qmk.fm)に提供でき、[qmk.fm](http://qmk.fm) で利用可能になります。ダウンロード出来るファイルは `//`(名前は上記と同じ形式)に保存され、`http://qmk.fm//` で提供されます。ページは `/_pages//` から生成されて、同じ場所で提供されます( .mdファイルはJekyllを通して .htmlファイル変換されます)。`lets_split` ファイルを参照して下さい。 + +## キーボードのデフォルト設定 + +QMK が提供する機能の量を考えれば、新しいユーザーが混乱するのは当たり前です。キーボードのデフォルトファームウェアをまとめるなら、有効にする機能とオプションをハードウェアのサポートに必要な最低限のセットにすることをおすすめします。特定の機能に関するおすすめは以下の通りです。 + +### ブートマジックとコマンド + +[ブートマジック](ja/feature_bootmagic.md) と[コマンド](ja/feature_command.md)は、ユーザーがキーボードを明白でない方法で制御出来るようにする2つの関連機能です。いずれかの機能を有効にする場合、この機能をどのように提供するかについて、よく考えることをおすすめします。この機能が必要なユーザーは、あなたのキーボードを最初のプログラムできるキーボードとして使用している初心者に影響を与えることなく、個人的なキーマップ内で有効に出来ることを覚えておきましょう。 + +新規ユーザーが遭遇する最も多い問題は、キーボードを接続している間に間違えてブートマジックをトリガーしてしまうことです。キーボードの下を持っているとき、知らない間に Alt とスペースバーを押して、これらのキーが交換されてしまったことに気づきます。デフォルトではこの機能を無効にすることをおすすめしますが、有効にする場合は、キーボードを接続している間に押し間違えないキーへ `BOOTMAGIC_KEY_SALT` を設定することを検討して下さい。 + +キーボードに2つの Shift キーがない場合は、`COMMAND_ENABLE = no` を指定していても `IS_COMMAND` が動作するデフォルトを設定しておくべきです。ユーザーがコマンドを有効化したときに使用するデフォルトが与えられます。 + +## カスタムキーボードプログラミング + +[機能のカスタマイズ](ja/custom_quantum_functions.md)にあるようにキーボードのカスタム関数を定義できます。ユーザーも同様にその動作をカスタマイズしたいかもしれないということと、ユーザーにそれを可能にすることを忘れないで下さい。 `process_record_kb()`のようなカスタム関数を提供している場合、関数がその関数の `_user()` 版を呼び出すことを確認して下さい。また、その関数の`_user()` 版の戻り値を確認して、user が `true` を返した場合のみカスタムコードを実行しなければいけません。 + +## 生産しない/手配線 プロジェクト + +プロトタイプや手配線によるものなど QMK を使用するどんなプロジェクトも受け入れますが、`/keyboards/` フォルダが乱雑になるのを防ぐために、`/keyboards/handwired/` を用意しています。いつかプロトタイプのプロジェクトが製品のプロジェクトになった時点でメインの `/keyboards/` フォルダへ移動します! + +## エラーとしての警告 + +キーボードを開発するときは、全ての警告がエラーとして扱われることに注意して下さい。小さな警告が蓄積されて、将来大きなエラーを引き起こす可能性があります。(そして、警告を放っておくのは良くない習慣です) + +## 著作権表示 + +別のプロジェクトを元にしてキーボードの設定をするものの同じコードを使用しない場合は、ファイル上部にある著作権表示を次の形式に従って自分の名前を表示するよう、更新して下さい。 + + Copyright 2017 Your Name + + +他の人のコードを修正し、その変更が些細な部分のみであれば、著作権表示の名前をそのままにしておかないといけません。ファイルに対して重要な作業を行った場合、以下のようにあなたの名前を追加します。 + + Copyright 2017 Their Name Your Name + +年はファイルが作成された最初の年にします。後年にそのファイルに対して作業が行われた場合、次のように2つ目の年を追加して反映することが出来ます。 + + Copyright 2015-2017 Your Name + +## ライセンス + +QMK のコア部分は [GNU General Public License](https://www.gnu.org/licenses/licenses.en.html) でライセンスされます。AVR マイコン用のバイナリを提供する場合は、[GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) か、[GPLv3](https://www.gnu.org/licenses/gpl.html) のどちらかから選択出来ます。ARM マイコン用のバイナリを提供する場合は、 [ChibiOS](http://www.chibios.org) の GPLv3 ライセンスに準拠するため、[GPL Version 3](https://www.gnu.org/licenses/gpl.html) を選択しなければいけません。 + +[uGFX](https://ugfx.io) を使用している場合は、[uGFX License](https://ugfx.io/license.html) に準拠する必要があります。uGFX を利用したデバイスを販売するには個別に商用ライセンスを取得しなければいけません。 + +## 技術的な詳細 + +キーボードを QMK で動作させるための詳細は[ハードウェア](ja/hardware.md)を参照して下さい! diff --git a/ja/how_a_matrix_works.md b/ja/how_a_matrix_works.md new file mode 100644 index 00000000000..b6ded186baf --- /dev/null +++ b/ja/how_a_matrix_works.md @@ -0,0 +1,104 @@ +# キーボードマトリックスの仕組み + + + +キーボードスイッチのマトリックスは行と列に配置されます。マトリックス回路がなければ、各スイッチはコントローラに直接配線する必要があります。 + +回路が行と列に配置されている場合、キーが押されると、列ワイヤが行ワイヤと接触し、回路が完成します。キーボードコントローラはこの閉回路を検知し、キー押下として登録します。 + +マイクロコントローラはファームウェアを介してセットアップされ、論理1を一度に1つずつ列に送信し、行から一度に全てを読み取ります - このプロセスはマトリックススキャンと呼ばれます。マトリックスはデフォルトでは電流の通過を許可しないたくさんの開いたスイッチです - ファームウェアはキーが押されていないものとしてこれを読み取ります。1つのキーを押すとすぐに、キースイッチが接続されている列から来ていた論理1がスイッチを通過して対応する行に渡されます - 以下の 2x2 の例を確認してください: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + row0 ---(key0)---(key1) row0 ---(key0)---(key1) + | | | | + row1 ---(key2)---(key3) row1 ---(key2)---(key3) + +`x` は関連付けられた列と行の値が1であるか、HIGH であることを表します。ここでは、キーが押されていないことが分かります。そのため `x` を取得する行はありません。1つのキースイッチの二つの接点はそのスイッチのある行と列にそれぞれ接続されていることに注意してください。 + +`key0` を押すと、`col0` は `row0` に接続されるため、ファームウェアがその行に対して受け取る値は `0b01` です (ここで `0b` はこれがビット値であることを意味します。つまり次の数字は全てビット(0または1)であり、その列のキーを表します)。この表記を使用して、キースイッチが押されたことを示し、列と行が接続されていることを示します: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1) + | | | | + row1 ---(key2)---(key3) row1 ---(key2)---(key3) + +`row0` には `x` があるため、値が1であることがわかります。全体として、`key0` が押された時にファームウェアが受信するデータは、 + + col0: 0b01 + col1: 0b00 + │└row0 + └row1 + +一度に複数のキーを押し始めると問題が発生します。マトリックスをもう一度見ると、かなり明白になっているはずです: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + | | | | + x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1) + | | | | + x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3) + + Remember that this ^ is still connected to row1 + +これから取得されるデータは以下の通りです: + + col0: 0b11 + col1: 0b11 + │└row0 + └row1 + +4つ全てではなく、3つのキーしか押されていないため、これは正確ではありません。この挙動はゴーストと呼ばれ、このような奇妙なシナリオでのみ発生しますが、より大きなキーボードではより一般的です。これを回避する方法は、キースイッチの後に、行に接続する前にダイオードを配置することです。ダイオードは、電流が一方向にのみ流れるようにします。これにより、前の例で他の列と行がアクティブにならないようにします。ダイオードマトリックスをこのように表します; + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + │ │ | │ + (key0) (key1) (key0) (key1) + ! │ ! │ ! | ! │ + row0 ─────┴────────┘ │ row0 ─────┴────────┘ │ + │ │ | │ + (key2) (key3) (key2) (key3) + ! ! ! ! + row1 ─────┴────────┘ row1 ─────┴────────┘ + +実際の用途では、ダイオードの黒い線が行に面するように、キースイッチから離れるように配置されます - この場合の `!` はダイオードで、隙間は黒い線を表します。これを覚える良い方法は、以下のシンボルを考えることです: `>|` + +次に、3つのキーを押して、ゴーストシナリオとなるものを実施します: + + Column 0 being scanned Column 1 being scanned + x x + col0 col1 col0 col1 + │ │ │ │ + (┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1) + ! │ ! │ ! │ ! │ + x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │ + │ │ │ │ + (key2) (┌─┘3) (key2) (┌─┘3) + ! ! ! ! + row1 ─────┴────────┘ x row1 ─────┴────────┘ + +全てが期待通りに動きます!これにより、以下のデータが取得されます: + + col0: 0b01 + col1: 0b11 + │└row0 + └row1 + +ファームウェアはこの正しいデータを使って、何をすべきかを、最終的には OS に送信する必要のある信号を検出できます。 + +参考文献: +- [Wikipedia の記事](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit) +- [Deskthority の記事](https://deskthority.net/wiki/Keyboard_matrix) +- [Dave Dribin による Keyboard Matrix Help (2000)](https://www.dribin.org/dave/keyboard/one_html/) +- [PCBheaven による How Key Matrices Works](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (アニメーションの例) +- [キーボードの仕組み - QMK ドキュメント](ja/how_keyboards_work.md) diff --git a/ja/how_keyboards_work.md b/ja/how_keyboards_work.md new file mode 100644 index 00000000000..5c54e5ff73c --- /dev/null +++ b/ja/how_keyboards_work.md @@ -0,0 +1,74 @@ +# キーが登録され、コンピュータで解釈される仕組み + + + +このファイルでは、USB を介してキーボードがどのように動作するかの概念を学習できます。ファームウェアを直接変更することで何が期待できるかをより良く理解することができます。 + +## 概略図 + +特定のキーを1つ入力するたびに、このような一連のアクションが発生します: + +```text ++------+ +-----+ +----------+ +----------+ +----+ +| User |-------->| Key |------>| Firmware |----->| USB wire |---->| OS | ++------+ +-----+ +----------+ +----------+ +----+ +``` + +この図は何が起こっているかを非常に単純に示したものです。詳細については次のセクションで説明します。 + +## 1. キーを押す + +キーを押すたびに、キーボードのファームウェアはこのイベントを登録することができます。 +キーが押され、保持され、放された時に登録することができます。 + +これは通常キー押下の定期的な走査で発生します。多くの場合、キーの機械的な応答時間、キー押下情報を転送するプロトコル(ここでは USB HID)、あるいは使用されるソフトウェアによって、この速度は制限されます。 + +## 2. ファームウェアが送信するもの + +[HID 仕様](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf)では、適切に認識されるためにキーボードが USB 経由で実際に送信できるものを規定しています。これには、`0x00` から `0xE7` までの単純な数字であるスキャンコードの定義済リストが含まれます。ファームウェアはスキャンコードをキーボードのそれぞれのキーに割り当てます。 + +ファームウェアは実際の文字を送信せず、スキャンコードだけを送信します。 +従って、ファームウェアを変更することで、特定のキーにたいして USB を介してどのスキャンコードが送信されるかだけを変更することができます。 + +## 3. イベント入力やカーネルが行うこと + +*スキャンコード*は、[マスターブランチの 60-keyboard.hwdb](https://github.com/systemd/systemd/blob/master/hwdb.d/60-keyboard.hwdb) キーボードに依存する*キーコード*にマップされます。このマッピングが無いと、オペレーティングシステムは有効なキーコードを受信せず、キー押下で何も有用なことができません。 + +## 4. オペレーティングシステムがすること + +キーコードがオペレーティングシステムに到達すると、ソフトウェアの一部はキーボードのレイアウトによって、実際の文字と照合しなければなりません。例えば、レイアウトが QWERTY に設定されている場合、照合テーブルの例は以下の通りです: + +| キーコード | 文字 | +|---------|-----------| +| 0x04 | a/A | +| 0x05 | b/B | +| 0x06 | c/C | +| ... | ... | +| 0x1C | y/Y | +| 0x1D | z/Z | +| ... | ... | + +## 説明をファームウェアに戻して + +(独自のものを作成していない限り)レイアウトは一般的に固定されているため、ファームウェアは実際には作業を簡単するためレイアウト名で直接キーコードを記述できます。これが、`KC_A` が実際に QWERTY で `0x04` を表す場合に行われることです。完全なリストは[キーコード](ja/keycodes.md)にあります。 + +## 送信できる文字のリスト + +ショートカットを別として、限られたキーコードのセットが限られたレイアウトにマップされていることは、**指定されたキーに割り当てることができる文字のリストは、レイアウト内に存在するものだけである**ことを意味します。 + +例えば、QWERTY US レイアウトがあり、1つのキーを `€` (ユーロ通貨記号)を生成するように割り当てたい場合、そうすることができないことを意味します。なぜなら、QWERTY US レイアウトはそのようなマッピングを持たないためです。QWERTY UK レイアウト、あるいは QWERTY US International を使うことでそれを修正することができます。 + +全ての Unicode を含むキーボードレイアウトがなぜ考案されていないのか疑問に思うかもしれません。USB を介して利用可能なキーコードの数の制限により、このようなことは許可されません。 + +## (おそらく) Unicode 文字を入力する方法 + +ファームウェアに *一連のキー* を送信させて、目的のオペレーティングシステムの[ソフトウェア Unicode インプットメソッド](https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_input)を使うことができます。このようにして、OS で定義されたレイアウトとは無関係に文字を効率的に入力することができます。 + +ただし、以下のような複数の欠点があります: + +- 一度に、一つの特定の OS に縛られます (OS を変更する時に再コンパイルする必要があります); +- 特定の OS では、全てのソフトウェアが動作するわけではありません; +- 一部のシステムでは Unicode のサブセットに制限されます。 diff --git a/ja/i2c_driver.md b/ja/i2c_driver.md new file mode 100644 index 00000000000..9d348d58033 --- /dev/null +++ b/ja/i2c_driver.md @@ -0,0 +1,138 @@ +# I2C マスタドライバ :id=i2c-master-driver + + + +QMK で使われる I2C マスタドライバには、MCU 間のポータビリティを提供するための一連の関数が用意されています。 + +## I2C アドレスについての重要なメモ :id=note-on-i2c-addresses + +このドライバが期待する全てのアドレスは、アドレスバイトの上位7ビットにプッシュする必要があります。最下位ビットの設定(読み込み/書き込みを示す)は、それぞれの関数によって行われます。データシートやインターネットで列挙されているほとんど全ての I2C アドレスは、下位7ビットを占める7ビットとして表され、1ビット左(より上位)にシフトする必要があります。これは、ビット単位のシフト演算子 `<< 1` を使用して簡単に実行できます。 + +これは、呼び出しごとに以下の関数を実行するか、アドレスの定義で1度だけ実行するかどちらかで行うことができます。例えば、デバイスのアドレスが `0x18` の場合: + +`#define MY_I2C_ADDRESS (0x18 << 1)` + +I2C アドレスと他の技術詳細について、さらなる情報を得るためには https://www.robot-electronics.co.uk/i2c-tutorial を見てください。 + +## 使用できる関数 :id=available-functions + +| 関数 | 説明 | +|-------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `void i2c_init(void);` | I2C ドライバを初期化します。他のあらゆるトランザクションを開始する前に、この関数を一度だけ呼ぶ必要があります。 | +| `i2c_status_t i2c_start(uint8_t address, uint16_t timeout);` | I2C トランザクションを開始します。アドレスは方向ビットのない7ビットスレーブアドレスです。 | +| `i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを送信します。アドレスは方向ビットのない7ビットスレーブアドレスです。トランザクションのステータスを返します。 | +| `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを受信します。アドレスは方向ビットのない7ビットスレーブアドレスです。 `length` で指定した長さのバイト列を `data` に保存し、トランザクションのステータスを返します。 | +| `i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_transmit` と同様ですが、 `regaddr` でスレーブのデータ書き込み先のレジスタを指定します。 | +| `i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_receive` と同様ですが、 `regaddr` でスレーブのデータ読み込み先のレジスタを指定します。 | +| `i2c_status_t i2c_stop(void);` | I2C トランザクションを終了します。 | + +### 関数の戻り値 :id=function-return + +`void i2c_init(void)` を除く上にあるすべての関数は、次の真理値表にある値を返します。 + +|戻り値の定数 |値 |説明 | +|--------------------|---|----------------------------| +|`I2C_STATUS_SUCCESS`|0 |処理が正常に実行されました。| +|`I2C_STATUS_ERROR` |-1 |処理に失敗しました。 | +|`I2C_STATUS_TIMEOUT`|-2 |処理がタイムアウトしました。| + +## AVR :id=avr + +### 設定 :id=avr-configuration + +I2Cマスタドライバを設定するために、次の定義が使えます。 + +| 変数 | 説明 | 既定値 | +|---------|---------------------|--------| +| `F_SCL` | クロック周波数 (Hz) | 400KHz | + + +AVR は通常 I2C ピンとして使う GPIO が設定されているので、これ以上の設定は必要ありません。 + +## ARM :id=arm + +ARM の場合は、内部に ChibiOS I2C HAL ドライバがあります。この節では STM32 MCU を使用していると仮定します。 + +### 設定 :id=arm-configuration + +ARM MCU 用の設定はしばしば非常に複雑です。これは、多くの場合複数の I2C ドライバをさまざまなポートに対して割り当てられるためです。 + +最初に、必要なハードウェアドライバを有効にするために `mcuconf.h` ファイルをセットアップします。 + +| 変数 | 説明 | 既定値 | +|-------------------------------|------------------------------------------------------------------------------------------------|--------| +| `#STM32_I2C_USE_XXX` | ハードウェアドライバ XXX の有効化/無効化(すべてのドライバを明示的にリストアップする必要あり) | FALSE | +| `#STM32_I2C_BUSY_TIMEOUT` | レスポンスの受信がない場合に I2C コマンドを中断するまでの時間 (ms) | 50 | +| `#STM32_I2C_XXX_IRQ_PRIORITY` | ハードウェアドライバ XXX の割り込み優先度(上級者向けの設定) | 10 | +| `#STM32_I2C_USE_DMA` | MCU がデータ送信を DMA ユニットにオフロードする機能の有効化/無効化 | TRUE | +| `#STM32_I2C_XXX_DMA_PRIORITY` | ハードウェアドライバ XXX に使用する DMA ユニットの優先度(上級者向けの設定) | 1 | + +次に `halconf.h` ファイル内で `#define HAL_USE_I2C` を `TRUE` にします。これにより ChibiOS が I2C ドライバを読み込みます。 + +最後に、使用したい I2C ハードウェアドライバに応じて正しい GPIO ピンを割り当てます。 + +標準では I2C1 ハードウェアドライバが使われます。もし他のハードウェアドライバを使う場合、 `config.h` ファイルに `#define I2C_DRIVER I2CDX` を追加します( X は使用するハードウェアドライバの番号です)。例えば I2C3 を有効化する場合、`config.h` ファイルに `#define I2C_DRIVER I2CD3` と定義します。これにより QMK I2C ドライバと ChibiOS I2C driver が同期されます。 + +STM32 MCU では、使用するハードウェアドライバにより、さまざまなピンを I2C ピンとして設定できます。標準では `B6`, `B7` ピンが I2C 用のピンです。 I2C 用のピンを設定するために次の定義が使えます: + +| 変数 | 説明 | 既定値 | +|-----------------------|--------------------------------------------------------------------------------------------------|---------| +| `I2C1_SCL_BANK` | SCL に使うピンのバンク (`GPIOA`, `GPIOB`, `GPIOC`) | `GPIOB` | +| `I2C1_SDA_BANK` | SDA に使うピンのバンク (`GPIOA`, `GPIOB`, `GPIOC`) | `GPIOB` | +| `I2C1_SCL` | SCL のピン番号 (0-15) | `6` | +| `I2C1_SDA` | SDA のピン番号 (0-15) | `7` | +| `I2C1_BANK`(非推奨) | 使用するピンのバンク (`GPIOA`, `GPIOB`, `GPIOC`)。後継は `I2C1_SCL_BANK`, `I2C1_SDA_BANK` です。 | `GPIOB` | + +ChibiOS I2C ドライバの設定項目は STM32 MCU の種類に依存します。 + + STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx, STM32L1xx では I2Cv1 が使われます。 + STM32F0xx, STM32F3xx, STM32F7xx, STM32L4xx では I2Cv2 が使われます。 + +#### I2Cv1 :id=i2cv1 + +STM32 MCU の I2Cv1 では、クロック周波数とデューティ比を次の変数で変更できます。詳しくは を参照してください。 + +| 変数 | 既定値 | +|--------------------|------------------| +| `I2C1_OPMODE` | `OPMODE_I2C` | +| `I2C1_CLOCK_SPEED` | `100000` | +| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` | + +#### I2Cv2 :id=i2cv2 + +STM32 MCU の I2Cv2 では、信号のタイミングパラメータを次の変数で変更できます。詳しくは を参照してください。 + +| 変数 | 既定値 | +|-----------------------|--------| +| `I2C1_TIMINGR_PRESC` | `15U` | +| `I2C1_TIMINGR_SCLDEL` | `4U` | +| `I2C1_TIMINGR_SDADEL` | `2U` | +| `I2C1_TIMINGR_SCLH` | `15U` | +| `I2C1_TIMINGR_SCLL` | `21U` | + +STM32 MCU では GPIO ピンを設定するとき、別の「代替機能」モードを使うことができます。これは I2Cv2 モードで使われるピンを変更するために必要です。適切な設定値は、使用している MCU のデータシートを参照してください。 + +| 変数 | 既定値 | +|---------------------|--------| +| `I2C1_SCL_PAL_MODE` | `4` | +| `I2C1_SDA_PAL_MODE` | `4` | + +#### その他 :id=other + +`void i2c_init(void)` 関数は `weak` 属性が付いており、オーバーロードすることができます。この場合、上記で設定した変数は使用されません。可能な GPIO の設定については、 MCU のデータシートを参照してください。次に示すのは初期化関数の例です: + +```c +void i2c_init(void) +{ + setPinInput(B6); // Try releasing special pins for a short time + setPinInput(B7); + wait_ms(10); // Wait for the release to happen + + palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function + palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function +} +``` diff --git a/ja/internals_gpio_control.md b/ja/internals_gpio_control.md new file mode 100644 index 00000000000..5f39e23e4fb --- /dev/null +++ b/ja/internals_gpio_control.md @@ -0,0 +1,28 @@ +# GPIO 制御 :id=gpio-control + + + +QMK には、マイクロコントローラに依存しない GPIO 制御抽象レイヤーがあります。これは異なるプラットフォーム間でピン制御に簡単にアクセスできるようにするためのものです。 + +## 関数 :id=functions + +以下の関数は GPIO の基本的な制御を提供し、`quantum/quantum.h` にあります。 + +| 関数 | 説明 | 古い AVR の例 | 古い ChibiOS/ARM の例 | +|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------| +| `setPinInput(pin)` | ピンを高インピーダンス(High-Z)の入力として設定 | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | +| `setPinInputHigh(pin)` | ピンを組み込みのプルアップ抵抗付きの入力として設定 | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | +| `setPinInputLow(pin)` | ピンを組み込みのプルダウン抵抗付きの入力として設定 | N/A (AVR ではサポートされません) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | +| `setPinOutput(pin)` | ピンを出力として設定 | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | +| `writePinHigh(pin)` | ピンレベルを high に設定 (ピンを出力として設定してあると仮定) | `PORTB \|= (1<<2)` | `palSetLine(pin)` | +| `writePinLow(pin)` | ピンレベルを low に設定 (ピンを出力として設定してあると仮定) | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | +| `writePin(pin, level)` | ピンレベルを設定 (ピンを出力として設定してあると仮定) | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | +| `readPin(pin)` | ピンのレベルを返す | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | +| `togglePin(pin)` | ピンレベルを反転 (ピンを出力として設定してあると仮定) | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | + +## 高度な設定 :id=advanced-settings + +各マイクロコントローラは GPIO に関して複数の高度な設定を持つことができます。この抽象レイヤーは、アーキテクチャー固有の機能の使用法を制限しません。上級ユーザは、目的のデバイスのデータシートを参照し、必要なライブラリを含めてください。AVR については、標準 avr/io.h ライブラリが使われます; STM32 については ChibiOS [PAL ライブラリ](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html)が使われます。 diff --git a/ja/internals_input_callback_reg.md b/ja/internals_input_callback_reg.md new file mode 100644 index 00000000000..517873b7caf --- /dev/null +++ b/ja/internals_input_callback_reg.md @@ -0,0 +1,174 @@ +# group `input_callback_reg` {#group__input__callback__reg} + + + +これらは受信コールバックを登録するために使用する関数です。 + +関数は、適切な midi メッセージが関連するデバイスの入力と一致した場合に呼び出されます。 + +## 概要 + +| メンバー | 説明 | +--------------------------------|--------------------------------------------- +| `public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | コントロールチェンジメッセージ受信コールバックを登録する。 | +| `public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | ノートオン受信コールバックを登録する。 | +| `public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | ノートオフ受信コールバックを登録する。 | +| `public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | アフタータッチ受信コールバックを登録する。 | +| `public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | ピッチベンド受信コールバックを登録する。 | +| `public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | ソングポジション受信コールバックを登録する。 | +| `public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | プログラムチェンジ受信コールバックを登録する。 | +| `public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | チャンネルプレッシャー受信コールバックを登録する。 | +| `public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | ソングセレクト受信コールバックを登録する。 | +| `public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | タイムコードクォータフレーム受信コールバックを登録する。 | +| `public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` | リアルタイム受信コールバックを登録する。 | +| `public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` | チューンリクエスト受信コールバックを登録する。 | +| `public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_sysex_func_t func)` | システムエクスクルーシブ受信コールバックを登録する。 | +| `public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` | フォールスルー受信コールバックを登録する。 | +| `public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` | キャッチオール受信コールバックを登録する。 | + +## メンバー + +#### `public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718} + +コントロールチェンジメッセージ受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga3962f276c17618923f1152779552103e} + +ノートオン受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d} + +ノートオフ受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f} + +アフタータッチ受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48} + +ピッチベンド受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6} + +ソングポジション受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127} + +プログラムチェンジ受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5} + +チャンネルプレッシャー受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72} + +ソングセレクト受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e} + +タイムコードクォータフレーム受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a} + +リアルタイム受信コールバックを登録する。 + +全てのリアルタイムメッセージ型に対してコールバックが呼ばれます。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1} + +チューンリクエスト受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_sysex_func_t func)` {#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48} + +システムエクスクルーシブ受信コールバックを登録する。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94} + +フォールスルー受信コールバックを登録する。 + +より具体的なコールバックが見つからない場合にのみ呼ばれます。例えば、ノートオン受信コールバックを登録していないがノートオンメッセージを受け取った場合、フォールスルー受信コールバックが登録されている場合はそれが呼ばれます。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + +#### `public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99} + +キャッチオール受信コールバックを登録する。 + +登録されている場合は、より具体的なコールバックあるいはフォールスルー受信コールバックが登録されている場合でも、一致する全てのメッセージに対してキャッチオール受信コールバックが呼ばれます。 + +#### パラメータ +* `device` 関連するデバイス + +* `func` 登録するコールバック関数 + diff --git a/ja/isp_flashing_guide.md b/ja/isp_flashing_guide.md new file mode 100644 index 00000000000..ae3918130e1 --- /dev/null +++ b/ja/isp_flashing_guide.md @@ -0,0 +1,284 @@ +# ISP 書き込みガイド + + + +ISP 書き込み(ICSP 書き込みと呼ぶ場合もあります)とは、マイクロコントローラーを直接プログラミングするプロセスです。 +これにより、ブートローダを交換したり、コントローラの「ヒューズ」を変更することができ、コントローラの速度や起動方法、その他のオプションなど、多くのハードウェアおよびソフトウェア関連の機能を制御します。 + +QMK の ISP 書き込みの主な用途は、AVRベースのコントローラ(Pro Micro、または V-USB チップ)のブートローダの書き込みまたは交換です。 + +?> これは Pro Micro や他の ATmega コントローラなどの AVR ベースのボードをプログラミングするためだけのものです。 Proton C などの Arm コントローラには使用できません。 + +## 破損したブートローダーの取り扱い + +ボードの書き込み/消去で問題が発生し、DFU ベースのコントローラで次のような不可解なエラーメッセージが表示される場合: + + libusb: warning [darwin_transfer_status] transfer error: timed out + dfu.c:844: -ETIMEDOUT: Transfer timed out, NAK 0xffffffc4 (-60) + atmel.c:1627: atmel_flash: flash data dfu_download failed. + atmel.c:1629: Expected message length of 1072, got -60. + atmel.c:1434: Error flashing the block: err -2. + ERROR + Memory write error, use debug for more info. + commands.c:360: Error writing memory data. (err -4) + + dfu.c:844: -EPIPE: a) Babble detect or b) Endpoint stalled 0xffffffe0 (-32) + Device is write protected. + dfu.c:252: dfu_clear_status( 0x7fff4fc2ea80 ) + atmel.c:1434: Error flashing the block: err -2. + ERROR + Memory write error, use debug for more info. + commands.c:360: Error writing memory data. (err -4) + +または、Pro Micro ベースのコントローラに対して次のようなメッセージが表示された場合: + + avrdude: butterfly_recv(): programmer is not responding + avrdude: butterfly_recv(): programmer is not responding + avrdude: verification error, first mismatch at byte 0x002a + 0x2b != 0x75 + avrdude: verification error; content mismatch + avrdude: verification error; content mismatch + + +あなたのボード/デバイスを再び動作させるには、ISP 書き込みが必要になるかもしれません。 + +## 必要なハードウェア + +実際に ISP の書き込みを行うには、以下のいずれか(その後に使用するプロトコルが続きます)が必要になります。 + +* [SparkFun PocketAVR](https://www.sparkfun.com/products/9825) - (USB Tiny) +* [USBtinyISP AVR Programmer Kit](https://www.adafruit.com/product/46) - (USB Tiny) +* [Teensy 2.0](https://www.pjrc.com/store/teensy.html) - (avrisp) +* [Pro Micro](https://www.sparkfun.com/products/12640) - (avrisp) +* [Bus Pirate](https://www.adafruit.com/product/237) - (buspirate) + +ISP 書き込みに使用できるデバイスは他にもありますが、これらが主なものです。 +また、すべての製品リンクは公式バージョンへのものです。他の場所で入手することもできます。 + +また、「ISP プログラマ」をプログラミングするデバイスに配線するためのものも必要になります。 +PCB の中には直接使用できる ISP ヘッダがあるものもありますが、そうではない場合が多いので、コントローラ自体にハンダ付けするか、別のスイッチや他のコンポーネントにハンダ付けする必要があるでしょう。 + +### ISP ファームウェア + +Teensy と Pro Micro のコントローラを ISP プログラマとして使用するには、コントローラに ISP ファームウェアを書き込む必要があります。 +それ以外のハードウェアは、あらかじめプログラムされているはずです。 +そのため、これらのコントローラの場合は、正しい hex ファイルをダウンロードしてから書き込んでください。 + +* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`) +* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) (`10/B6`) + +コントローラに書き込んだら、この hex ファイルはもう必要ありません。 + +## 必要なソフトウェア + +QMK ツールボックスは、このほとんど(すべて)に使用することができます。 + +ただし、Teensy 2.0 ボードを使っている場合は、[Teensy Loader](https:/www.pjrc.comteensyloader.html) を使えば、Teensy 2.0 ボードに書き込むことができます。 +あるいは、`avrdude` (`qmk_install.sh` の一部としてインストールされています) や、[AVRDUDESS](https:/blog.zakkemble.netavrdudess-a-gui-for-avrdude)(Windows 用) を使って、Pro Micro に書き込んだり、ISP を書き込んだりすることができます。 + +## 配線 + +これは非常に簡単です。次のようにして、相互に対応するものを接続します。 + +### SparkFun Pocket AVR + + PocketAVR RST <-> Keyboard RESET + PocketAVR SCLK <-> Keyboard B1 (SCLK) + PocketAVR MOSI <-> Keyboard B2 (MOSI) + PocketAVR MISO <-> Keyboard B3 (MISO) + PocketAVR VCC <-> Keyboard VCC + PocketAVR GND <-> Keyboard GND + +### Teensy 2.0 + + Teensy B0 <-> Keyboard RESET + Teensy B1 <-> Keyboard B1 (SCLK) + Teensy B2 <-> Keyboard B2 (MOSI) + Teensy B3 <-> Keyboard B3 (MISO) + Teensy VCC <-> Keyboard VCC + Teensy GND <-> Keyboard GND + +!> Teensy の B0 ピンはキーボードのコントローラの RESET/RST ピンと配線されています。 Teensy の RESET ピンをキーボードの RESET に配線しないでください。 + +### Pro Micro + + Pro Micro 10 (B6) <-> Keyboard RESET + Pro Micro 15 (B1) <-> Keyboard B1 (SCLK) + Pro Micro 16 (B2) <-> Keyboard B2 (MOSI) + Pro Micro 14 (B3) <-> Keyboard B3 (MISO) + Pro Micro VCC <-> Keyboard VCC + Pro Micro GND <-> Keyboard GND + +!> Pro Micro の 10/B6 ピンはキーボードのコントローラの RESET/RST ピンに配線されています。 Pro Micro の RESET ピンをキーボードの RESET に配線 ***しないでください***。 + +## キーボードへの書き込み + +ISP プログラマをセットアップして、キーボードに接続したら、キーボードに書き込みをします。 + +### ブートローダファイル + +普通の状態に戻す一番簡単で手っ取り早い方法は、キーボードにブートローダだけ書き込むことです。 +これが終れば、普通にキーボードを接続して、普通にキーボードに書き込みできるようになります。 + +標準のブートローダは[`util/` フォルダー](https://github.com/qmk/qmk_firmware/tree/master/util) にあります。 +チップの正しいブートローダを書き込んでください: + +* **Atmel DFU** + * [ATmega16U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega16u4_1.0.1.hex) + * [ATmega32U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1.0.0.hex) + * [AT90USB64](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb64_1.0.0.hex) + * [AT90USB128](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128_1.0.1.hex) +* **Caterina** + * [Pro Micro (5V/16MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro16.hex) + * [Pro Micro (3.3V/8MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro8.hex) +* **BootloadHID (PS2AVRGB)** + * [ATmega32A](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_ps2avrgb_bootloadhid_1.0.1.hex) + +お使いのボードが何を使っているかわからない場合は、QMK のキーボード用の `rules.mk` ファイルを見てください。 +`MCU` と `BOOTLOADER` の行には必要な値が書かれています。これはボードのバージョンによって異なるかもしれません。 + +### 製造手法 + +ブートローダと通常のファームウェアを同時に書き込みたい場合、2つの方法があります。 +手動で行うか、コンパイル時に `:production` ターゲットを使って行うかです。 + +手動で行うには: + +1. オリジナルのファームウェアの .hex ファイルをテキストエディタで開きます +2. 最後の行を削除してください。(`:00000001FF`になっているはずです - これは EOF メッセージです) +3. ブートローダの内容全体を新しい行にコピーして(行間に空行を入れないように)、元のファイルの最後に貼り付けてください。 +4. これを新しいファイルとして `__production.hex` という名前で保存します。 + +?> ここでは他のブートローダも同じように使うことができますが、__ブートローダが必要で__、そうしないとまた ISP を使ってキーボードに新しいファームウェアを書き込まなければならなくなります。 + +#### QMK DFU ブートローダとプロダクションイメージの作成 + +コンパイル時に `:production` ターゲットを使用して、ボード用のファームウェア、QMK DFU ブートローダ、プロダクションファームウェアイメージを作成することができます。 +これが完了すると、3つのファイルが表示されます: + +* `_.hex` +* `__bootloader.hex` +* `__production.hex` + +QMK DFU ブートローダは `atmega32u4` コントローラ (AVR ベースの Planck ボードや Pro Micro など) でしかテストされておらず、他のコントローラではテストされていません。 +しかし、`atmega32a` や `atmega328p` のような V-USB コントローラでは間違いなく動作しません。 + +ブートローダかプロダクションファームウェアファイルのどちらかを書き込むことができます。 +プロダクションファームウェアファイルの方が、より多くのデータを書き込むので、書き込みに時間がかかります。 + +?> 注意:同じブートローダを使用しつづけるべきです。すでに DFU を使用している場合は、QMK DFU に切り替えても問題ありません。しかし、例えば Pro Micro に QMK DFU を書き込むには、追加の手順が必要になります。 + +## ブートローダ/プロダクションファイルの書き込み + +キーボードがどのデバイスにも接続されていないことを確認し、ISP プログラマを接続してください。 + +ブートローダの種類を変更したい場合は、コマンドラインを使用する必要があります。 + +### QMK Toolbox + +1. 'AVRISP device connected' または `USB Tiny device connected` が黄色で表示されます。 +2. `Open` ダイアログで正しいブートローダー/プロダクションの .hex ファイルを選択します(パスにスペースを含めることはできません) +3. 書きこもうとしているキーボード(ISP プログラマではなく)のための正しい `Microcontroller` オプションが選択されていることを確認してください。 +4. `Flash` を押します +5. 特にプロダクションファイルの場合、しばらくは何も出力されませんが、待ちましょう。 + +検証とヒューズのチェックに問題がなければ、完了です。 +ボードが自動的に再起動する場合があります。 +それ以外の場合は、Teensy のプラグを抜いて、キーボードを接続します。 +テスト中は、Teensy をキーボードに接続したままにすることができますが、すべてが正常に機能することを確認したら、はんだを外すか、配線を外すことをお勧めします。 + +### コマンドライン + +ターミナル(Windows の場合は `cmd`)を開いて、修正した .hex ファイルがある場所に移動します。 +ここでは、このファイルを `main.hex` と呼び、Teensy 2.0 が `COM3` ポートに接続されていると仮定します。 +よくわからない場合は、デバイスマネージャを開いて、`Ports > USB Serial Device` を探してください。ここにある COM ポートを使ってください。 +あなたはそれが正しいポートであることを確認することができます: + + avrdude -c avrisp -P COM3 -p atmega32u4 + +次のような出力が得られるはずです: + + avrdude: AVR device initialized and ready to accept instructions + + Reading | ################################################## | 100% 0.02s + + avrdude: Device signature = 0x1e9587 + + avrdude: safemode: Fuses OK + + avrdude done. Thank you. + +私たちのキーボードは `atmega32u4`(共通)を使用しているので、これが指定するチップです。 +以下が完全なコマンドです: + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i + +ボードが `atmega32a`(jj40 など)を使用している場合、コマンドは次のとおりです(最後の追加コードによりヒューズが正しく設定されます)。 + + avrdude -c avrisp -P COM3 -p atmega32 -U flash:w:main.hex:i -U hfuse:w:0xD0:m -U lfuse:w:0x0F:m + +プログレスバーが表示されてから、以下が表示されるはずです。 + + avrdude: verifying ... + avrdude: 32768 bytes of flash verified + + avrdude: safemode: Fuses OK + + avrdude done. Thank you. + +これは全てうまく動作したことを示しています。 +ボードが自動的に再起動する場合もありますが、そうでない場合は、Teensy のプラグを抜いてキーボードを接続してください。 +テスト中は、Teensy をキーボードに接続したままにすることができますが、すべてが正常に機能することを確認したら、はんだを外すか、配線を外すことをお勧めします。 + +SparkFun PocketAVR Programmer や、他の USB Tiny ベースの ISP プログラマを使用している場合は、次のようなものを使用すると良いでしょう。 + + avrdude -c usbtiny -P usb -p atmega32u4 + +#### 上級者向け: ヒューズの変更 + +Pro Micro に QMK DFU を書き込むなど、ブートローダを切り替える場合は、ブートローダの hex ファイルの書き込みに加えて、ヒューズを変更する必要があります。 +これは、`caterina` (Pro Micro ブートローダ) と `dfu` では起動ルーチンの扱いが異なり、その動作はヒューズによって制御されるからです。 + +!> これは、ヒューズを変更することは、永久にあなたのコントローラをレンガ化(訳注:日本では文鎮化と呼ぶことが多い、コントローラがまったく無反応になる状態)することができる方法の1つであるため、それは非常に注意が必要な1つの領域です。 + +以下は、`atmega32u4`の 5V 16MHz 版(5V Pro Micro など)を想定しています。 + +`atmega32u4`の DFU の場合、必要なヒューズ設定は次のとおりです: + +| ヒューズ | 設定 | +|----------|------------------| +| Low | `0x5E` | +| High | `0xD9` or `0x99` | +| Extended | `0xC3` | + +High ヒューズは 0xD9 か 0x99 のどちらかになります。 +違いは、0xD9 は QMK Firmware がソフトウェアでも無効化している JTAG を無効化しているのに対し、0x99 は JTAG を無効化していないことです。 + +これを設定するには、`-U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m` をコマンドに追加します。 +そうすると、最終的なコマンドは次のようになります。 + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m + +`atmega32u4`の Caterina では、以下があなたに必要なヒューズの設定です。 + +| ヒューズ | 設定 | +|----------|--------| +| Low | `0xFF` | +| High | `0xD8` | +| Extended | `0xCB` | + +これを設定するには、コマンドに `-U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m` を追加します。 +これで、最終的なコマンドは次のようになるはずです。 + + avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m + + +別のコントローラーを使用している場合や、別の設定を希望する場合は、この[AVR ヒューズ計算機](http:/www.engbedded.comfusecalc)を使用して、より適切な値を見つけることができます。 + +## ヘルプ + +ご質問・ご不明な点がありましたら、お気軽に[issue を開いてください](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/ja/keymap.md b/ja/keymap.md new file mode 100644 index 00000000000..7614e52433f --- /dev/null +++ b/ja/keymap.md @@ -0,0 +1,187 @@ +# キーマップの概要 + + + +QMK のキーマップは C のソースファイルの中で定義されます。そのデータ構造は配列の配列です。外側はレイヤーを要素とする配列で、レイヤーはキーを要素とする配列。ほとんどのキーボードは `LAYOUT()` マクロを定義して、この配列の配列を作成しやすくしています。 + + +## キーマップとレイヤー :id=keymap-and-layers +QMKでは、**`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`**は、**アクションコード**を保持している **16 bit** データの中でキーマップ情報の複数の**レイヤー**を保持します。最大で**32個のレイヤー**を定義することができます。 + +普通のキー定義の場合、**アクションコード**の上位8ビットは全て0で、下位8ビットは**キーコード**としてキーによって生成された USB HID usage コードを保持します。 + +各レイヤーは同時に有効にできます。レイヤーには 0 から 31 までのインデックスが付けられ、上位のレイヤーが優先されます。 + + Keymap: 32 Layers Layer: action code matrix + ----------------- --------------------- + stack of layers array_of_action_code[row][column] + ____________ precedence _______________________ + / / | high / ESC / F1 / F2 / F3 .... + 31 /___________// | /-----/-----/-----/----- + 30 /___________// | / TAB / Q / W / E .... + 29 /___________/ | /-----/-----/-----/----- + : _:_:_:_:_:__ | : /LCtrl/ A / S / D .... + : / : : : : : / | : / : : : : + 2 /___________// | 2 `-------------------------- + 1 /___________// | 1 `-------------------------- + 0 /___________/ V low 0 `-------------------------- + + +TMK の歴史的経緯から、キーマップに保存されたアクションコードは、一部のドキュメントではキーコードと呼ばれる場合があります。 + +### キーマップレイヤーステータス :id=keymap-layer-status + +キーマップレイヤーの状態は、2つの32ビットパラメータによって決定されます。 + +* **`default_layer_state`** は、常に有効で参照される基本キーマップレイヤー (0-31) を示します (デフォルトレイヤー)。 +* **`layer_state`** は現在の各レイヤーのオン/オフの状態をビットで持ちます。 + +キーマップレイヤー '0' は通常 `default_layer` で、他のレイヤーはファームウェアの起動後に最初はオフになっていますが、これは `config.h` で異なる設定にすることが可能です。例えば Qwerty ではなく Colemak に切り替えるなど、キーレイアウトを完全に切り替える場合、`default_layer` を変更すると便利です。 + + Initial state of Keymap Change base layout + ----------------------- ------------------ + + 31 31 + 30 30 + 29 29 + : : + : : ____________ + 2 ____________ 2 / / + 1 / / ,->1 /___________/ + ,->0 /___________/ | 0 + | | + `--- default_layer = 0 `--- default_layer = 1 + layer_state = 0x00000001 layer_state = 0x00000002 + +一方、`layer_state` を変更して、基本レイヤーをナビゲーションキー、ファンクションキー (F1-F12)、メディアキー、特別なアクションなどの機能を持つ他のレイヤーでオーバーレイすることができます。 + + Overlay feature layer + --------------------- bit|status + ____________ ---+------ + 31 / / 31 | 0 + 30 /___________// -----> 30 | 1 + 29 /___________/ -----> 29 | 1 + : : | : + : ____________ : | : + 2 / / 2 | 0 + ,->1 /___________/ -----> 1 | 1 + | 0 0 | 0 + | + + `--- default_layer = 1 | + layer_state = 0x60000002 <-' + + + +### レイヤーの優先順位と透過性 +***上位のレイヤーはレイヤーのスタックでより高い優先順位を持つ***ことに注意してください。ファームウェアは最上位のアクティブレイヤーから下に向かってキーコードを検索します。ファームウェアがアクティブなレイヤーで `KC_TRNS` (透過)以外のキーコードを見つけると、検索を停止し、下位レイヤーは参照されません。 + + ____________ + / / <--- Higher layer + / KC_TRNS // + /___________// <--- Lower layer (KC_A) + /___________/ + + 上記シナリオでは、上位レイヤーに非透過のキーが定義されているとそのキーが使われますが、`KC_TRNS` (または同等のキーコード)が定義されている場合は常に下位レベルのキーコード(`KC_A`)が使われます。 + +**メモ:** 特定のレイヤーの透過性を示す有効な方法: +* `KC_TRANSPARENT` +* `KC_TRNS` (別名) +* `_______` (別名) + +これらのキーコードは、処理する非透過のキーコードを探すときに、下位レイヤーを検索させることができます。 + +## `keymap.c` の分析 + +この例では、[デフォルトの Clueboard 66% キーマップの古いバージョン](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c)を見ていきます。そのファイルを別のブラウザウィンドウで開くとコンテキスト内のすべてを見ることができるので便利です。 + +`keymap.c` ファイルには、あなたが関心があるであろう以下の2つの主要なセクションがあります: + +* [定義](#definitions) +* [レイヤー/キーマップデータ構造](#layers-and-keymaps) + +### 定義 :id=definitions + +ファイルの上部に以下のものがあります: + + #include QMK_KEYBOARD_H + + // 便利な定義 + #define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * KC_TRNS (透過) の代わりに _______ を使うことができます * + * あるいは、KC_NO (NOOP) として XXXXXXX を使うことができます * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + // 各レイヤーは読みやすいように名前を持ちます。 + // アンダースコアは何も意味を持ちません + // STUFF あるいは他の名前のレイヤーを持つことができます。 + // レイヤー名は全て同じ長さである必要はなく、 + // また名前を完全に省略して単に数字を使うことができます。 + #define _BL 0 + #define _FL 1 + #define _CL 2 + +これらはキーマップとカスタム関数を作成するときに使うことができる便利な定義です。`GRAVE_MODS` 定義は後でカスタム関数で使われ、その下の `_BL`、`_FL`、`_CL` 定義は各レイヤーを参照しやすくします。 + +注意: 古いキーマップファイルに `_______` および `XXXXXXX` の定義が含まれているかもしれません。これらはそれぞれ `KC_TRNS` および `KC_NO` の代わりに使うことができ、レイヤーがどのキーを上書きしているかを簡単に確認することができます。これらの定義はデフォルトで含まれるため、今では不要になりました。 + +### レイヤーとキーマップ :id=layers-and-keymaps + +このファイルの主要部分は `keymaps[]` 定義です。ここで、レイヤーとそれらの内容を列挙します。ファイルのこの部分は、以下の定義から始まります: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +この後で、LAYOUT() マクロのリストがあります。LAYOUT() は単一のレイヤーを定義するためのキーのリストです。通常、1つ以上の"基本レイヤー" (QWERTY、Dvorak、Colemak など)があり、その上に1つ以上の"機能"レイヤーを重ねます。レイヤーの処理方法により、"より上位"のレイヤーの上に"より下位"のレイヤーを重ねることはできません。 + +QMK の `keymaps[][MATRIX_ROWS][MATRIX_COLS]` は、16ビットのアクションコード( quantum キーコードとも呼ばれる)を保持します。一般的なキーを表すキーコードの場合、その上位バイトは0で、その下位バイトはキーボードの USB HID usage ID です。 + +> QMK のフォーク元の TMK は、代わりに `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` を使い、8ビットキーコードを保持します。一部のキーコード値は、`fn_actions[]` 配列を介して特定のアクションコードの実行を引き起こすために予約されています。 + +#### 基本レイヤー + +Clueboard の基本レイヤーの例です: + + /* Keymap _BL: Base Layer (Default Layer) + */ + [_BL] = LAYOUT( + F(0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_BSPC, KC_PGUP, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, \ + KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_RSFT, KC_UP, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_MHEN, KC_SPC,KC_SPC, KC_HENK, KC_RALT, KC_RCTL, MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT), + +これについて注意すべきいくつかの興味深いこと: + +* C ソースの観点からは、これは単一の配列に過ぎませんが、物理デバイス上の各キーがどこにあるかをより簡単に可視化するために、空白が埋め込まれています。 +* 単純なキーボードスキャンコードの先頭には KC_ が付いていますが、"特別な"キーには付いていません。 +* 左上のキーはカスタム機能 0 (`F(0)`) をアクティブにします。 +* "Fn" キーは `MO(_FL)` で定義され、そのキーが押されている間は `_FL` レイヤーに移動します。 + +#### 機能オーバーレイレイヤー + +機能レイヤーはコードの観点から基本レイヤーと違いはありません。ただし概念的には、置き換えの代わりにオーバーレイとしてそのレイヤーを構築します。多くの人にとってはこの区別は重要ではありませんが、より複雑なレイヤー設定を構築するにつれて、ますます重要になります。 + + [_FL] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_DEL, BL_STEP, \ + _______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK, KC_PAUS, _______, _______, _______, _______, \ + _______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ + _______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, \ + _______, _______, _______, _______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END), + +注意すべきいくつかの興味深いこと: + +* `_______` 定義を使って、`KC_TRNS` を `_______` に変換しました。これによりこのレイヤーで変更されたキーを簡単に見つけることができます。 +* このレイヤーで `_______` キーのいずれかを押すと、次の下位のアクティブなレイヤーのキーがアクティブになります。 + +# 核心となる詳細 + +これで独自のキーマップを作成するための基本的な概要が得られました。詳細は以下のリソースを見てください: + +* [キーコード](ja/keycodes.md) +* [キーマップ FAQ](ja/faq_keymap.md) + +これらのドキュメントの改善に積極的に取り組んでいます。それらを改善する方法について提案がある場合は、[issue を報告](https://github.com/qmk/qmk_firmware/issues/new)してください! diff --git a/ja/mod_tap.md b/ja/mod_tap.md new file mode 100644 index 00000000000..ca74ba2ebf0 --- /dev/null +++ b/ja/mod_tap.md @@ -0,0 +1,59 @@ +# モッドタップ + + + +モッドタップキー `MT(mod, kc)` は、押したままの時にモディファイアのように機能し、タップされた時に通常のキーのように振舞います。別の言い方をすると、タップした時に Escape を送信しますが、押したままの時に Control あるいは Shift キーとして機能するキーを持つことができます。 + +このキーコードと `OSM()` が受け付けるモディファイアは、`KC_` ではなく、`MOD_` の接頭辞が付いています: + +| モディファイア | 説明 | +|----------------|----------------------------------------------| +| `MOD_LCTL` | 左 Control | +| `MOD_LSFT` | 左 Shift | +| `MOD_LALT` | 左 Alt | +| `MOD_LGUI` | 左 GUI (Windows/Command/Meta キー) | +| `MOD_RCTL` | 右 Control | +| `MOD_RSFT` | 右 Shift | +| `MOD_RALT` | 右 Alt (AltGr) | +| `MOD_RGUI` | 右 GUI (Windows/Command/Meta キー) | +| `MOD_HYPR` | Hyper (左 Control、左 Shift、左 Alt、左 GUI) | +| `MOD_MEH` | Meh (左 Control、左 Shift、左 Alt) | + +以下のようにそれらを OR することで、これらを組み合わせることができます: + +```c +MT(MOD_LCTL | MOD_LSFT, KC_ESC) +``` + +押したままの時にこのキーは左 Control および左 Shift をアクティブにし、タップされた時に Escape を送信します。 + +便利なように、QMK はキーマップで一般的な組み合わせをよりコンパクトにするためのモッドタップショートカットを含んでいます: + +| キー | エイリアス | 説明 | +|--------------|-----------------------------|-------------------------------------------------------------| +| `LCTL_T(kc)` | `CTL_T(kc)` | 押したままの場合は左 Control、タップした場合は `kc` | +| `LSFT_T(kc)` | `SFT_T(kc)` | 押したままの場合は左 Shift、タップした場合は `kc` | +| `LALT_T(kc)` | `LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` | 押したままの場合は左 Alt、タップした場合は `kc` | +| `LGUI_T(kc)` | `LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)` | 押したままの場合は左 GUI、タップした場合は `kc` | +| `RCTL_T(kc)` | | 押したままの場合は右 Control、タップした場合は `kc` | +| `RSFT_T(kc)` | | 押したままの場合は右 Shift、タップした場合は `kc` | +| `RALT_T(kc)` | `ROPT_T(kc)`, `ALGR_T(kc)` | 押したままの場合は右 Alt、タップした場合は `kc` | +| `RGUI_T(kc)` | `RCMD_T(kc)`, `RWIN_T(kc)` | 押したままの場合は右 GUI、タップした場合は `kc` | +| `SGUI_T(kc)` | `SCMD_T(kc)`, `SWIN_T(kc)` | 押したままの場合は左 Shift と左 GUI、タップした場合は `kc` | +| `LCA_T(kc)` | | 押したままの場合は左 Control と左 Alt、タップした場合は `kc` | +| `LCAG_T(kc)` | | 押したままの場合は左 Control、左 Alt と左 GUI、タップした場合は `kc` | +| `RCAG_T(kc)` | | 押したままの場合は右 Control、右 Alt と右 GUI、タップした場合は `kc` | +| `C_S_T(kc)` | | 押したままの場合は左 Control と左 Shift、タップした場合は `kc` | +| `MEH_T(kc)` | | 押したままの場合は左 Control、左 Shift と左 Alt、タップした場合は `kc` | +| `HYPR_T(kc)` | `ALL_T(kc)` | 押したままの場合は左 Control、左 Shift、左 Alt と左 GUI、タップした場合は `kc` - より詳しくは[ここ](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)を見てください | + +## 注意事項 + +残念ながら、キーコードで指定されたモディファイアは無視されるため、これらのキーコードはモッドタップまたはレイヤータップで使うことができません。 + +さらに、Windows でリモートデスクトップ接続を使う場合に、問題が発生する場合があります。これらのコードはシフトを非常に高速に送信するため、リモートデスクトップはコードを見逃すかもしれません。 + +これを修正するには、リモートデスクトップ接続を開き、「オプションの表示」を開き、「ローカル リソース」タブを開きます。キーボードセクションで、ドロップダウンを「このコンピューター」に変更します。これにより問題が修正され、キャラクタが正しく動作するようになります。 diff --git a/ja/newbs.md b/ja/newbs.md new file mode 100644 index 00000000000..b582bc42567 --- /dev/null +++ b/ja/newbs.md @@ -0,0 +1,48 @@ +# QMK 初心者ガイド + + + +キーボードには、コンピュータ入っているものと似たようなプロセッサが入っています。 +このプロセッサでは、キーボードのボタンの押し下げの検出を担当し、キーが押されたときにコンピュータに通知するソフトウェアが動作しています。 +QMK Firmware は、そのソフトウェアの役割を果たし、ボタンの押下を検出しその情報をホストコンピュータに渡します。 +カスタムキーマップを作るということは、キーボード上で動くプログラムを作るということなのです。 + +QMK は、簡単なことは簡単に、そして、難しいことを可能なことにすることで、あなたの手にたくさんのパワーをもたらします。 +パワフルなキーマップを作るためにプログラムを作成する方法を知る必要はありません。いくつかのシンプルな文法に従うだけで OK です。 + +お使いのキーボードで QMK を実行できるかどうか不明ですか? +もし作成したキーボードがメカニカルキーボードの場合、実行できる可能性が高いです。 +QMK は[多くの趣味のキーボード](http://qmk.fm/keyboards/)をサポートしています。 +現在使用しているキーボードが QMK を実行できない場合、QMK を実行できるキーボードの選択肢はたくさんあります。 + +## このガイドは私のためにあるのでしょうか? + +このガイドは、ソースコードを使ってキーボードのファームウェアを構築したいと考えている人に適しています。 +もしあなたがすでにプログラマーであれば、このプロセスはとても身近で簡単に理解できるでしょう。 +もし、プログラミングの考え方に抵抗があるのであれば、代わりに[私たちのオンラインGUI](ja/newbs_building_firmware_configurator.md)を見てみてください。 + +## 概要 + +このガイドには4つの主要なセクションがあります。 + +1. [環境設定](ja/newbs_getting_started.md) +2. [コマンドラインを使用して初めてのファームウェアを構築する](ja/newbs_building_firmware.md) +3. [ファームウェアを書きこむ](ja/newbs_flashing.md) +4. [テストとデバッグ](ja/newbs_testing_debugging.md) + +このガイドは、これまでソフトウェアをコンパイルしたことがない人を支援することに特化しています。 +その観点から選択と推奨を行います。 +これらの手順の多くには代替方法があり、これらの代替方法のほとんどをサポートしています。 +タスクを達成する方法について疑問がある場合は、[案内を求めることができます](ja/getting_started_getting_help.md)。 + +## 追加のリソース + +このガイドの他にも、QMK の学習に役立つリソースがいくつかあります。[学習リソース](ja/newbs_learn_more_resources.md)のページにまとめました。 + +## オープンソース + +QMKは GNU General Public License でリリースされているオープンソース・ソフトウェアです。 diff --git a/ja/newbs_building_firmware.md b/ja/newbs_building_firmware.md new file mode 100644 index 00000000000..563efa71633 --- /dev/null +++ b/ja/newbs_building_firmware.md @@ -0,0 +1,81 @@ +# 初めてのファームウェアを構築する(コマンドライン版) + + + +ビルド環境をセットアップしたので、カスタムファームウェアのビルドを開始する準備ができました。 +ガイドのこのセクションでは、ファイルマネージャ、テキストエディタ、ターミナルウィンドウの3つのプログラム間を行き来します。 +キーボードファームウェアが完成して満足するまで、この3つすべてを開いたままにします。 + +## 新しいキーマップを作成する + +独自のキーマップを作成するには、`default` キーマップのコピーを作成する必要があります。最後のステップでビルド環境を設定した場合は、QMK CLI を使って簡単に行うことができます: + + qmk new-keymap + +もし環境が設定されていない場合や、複数のキーボードを所持している場合は、キーボード名を指定することができます: + + qmk new-keymap -kb + +そのコマンドの出力を見ると、次のようになっているはずです: + + Ψ keymap directory created in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/ + +これがあなたの新しい `keymap.c` ファイルの場所です。 + +## あなたの好みのテキストエディタで `keymap.c` を開く + +テキストエディタで `keymap.c` ファイルを開きます。 +このファイル内には、キーボードの動作を制御する構造があります。 +`keymap.c`の上部には、キーマップを読みやすくする定義と列挙型があります。 +さらに下には、次のような行があります: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +この行はレイヤーのリストの開始を表わしています。 +その下には、`LAYOUT` を含む行があり、これらの行はレイヤーの開始を表わしています。 +その行の下には、そのレイヤーを構成するキーのリストがあります。 + +!> キーマップファイルを編集するときは、カンマを追加したり削除したりしないように注意してください。そうするとファームウェアのコンパイルができなくなり、余分であったり欠落していたりするカンマがどこにあるのかを容易に把握できない場合があります。 + +## 好みに合わせてレイアウトをカスタマイズ + +納得のいくまでこのステップを繰り返します。 +気になる点をひとつづつ変更して試すのもよし、全部作りなおすのもよし。 +あるレイヤー全体が必要ない場合はレイヤーを削除することもでき、必要があれば、合計 32 個までレイヤーを追加することもできます。 +QMK にはたくさんの機能があり、完全なリストは左側のサイドバーの「QMK を使う」の下を調べてください。ここから始めるために、簡単に使える機能をいくつか紹介します: + +* [基本的なキーコード](ja/keycodes_basic.md) +* [Quantum キーコード](ja/quantum_keycodes.md) +* [グレイブ エスケープ](ja/feature_grave_esc.md) +* [マウスキー](ja/feature_mouse_keys.md) + +?> キーマップがどのように機能するかを感じながら、各変更を小さくしてください。大きな変更は、発生する問題のデバッグを困難にします。 + +## ファームウェアをビルドする :id=build-your-firmware + +キーマップの変更が完了したら、ファームウェアをビルドする必要があります。これを行うには、ターミナルウィンドウに戻り、コンパイルコマンドを実行します: + + qmk compile + +もし環境が設定されていない場合や、複数のキーボードを所持している場合は、キーボードやキーマップを指定することができます: + + qmk compile -kb -km + +これがコンパイルされる間、どのファイルがコンパイルされているかを知らせる多くの出力が画面に表示されます。 +次のような出力で終わるはずです: + +``` +Linking: .build/planck_rev5_default.elf [OK] +Creating load file for flashing: .build/planck_rev5_default.hex [OK] +Copying planck_rev5_default.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_default.hex [OK] + * The firmware size is fine - 27312/28672 (95%, 1360 bytes free) +``` + +## ファームウェアを書きこむ + +[「ファームウェアを書きこむ」](ja/newbs_flashing.md) に移動して、キーボードに新しいファームウェアを書き込む方法を学習します。 diff --git a/ja/newbs_building_firmware_configurator.md b/ja/newbs_building_firmware_configurator.md new file mode 100644 index 00000000000..61d25ffb52c --- /dev/null +++ b/ja/newbs_building_firmware_configurator.md @@ -0,0 +1,20 @@ +# QMK Configurator + + + +[![QMK Configurator Screenshot](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/) + +[QMK Configurator](https://config.qmk.fm) は、QMKファームウェアの hex ファイルを生成するオンライングラフィカルユーザーインターフェイスです。 + +[ビデオチュートリアル](https://www.youtube.com/watch?v=-imgglzDMdY) を見てください。 +多くの人は、それが自分のキーボードのプログラミングを始めるのに十分な情報であることに気づくでしょう。 + +QMK Configurator は Chrome/Firefox で最適に動作します。 + +!> **注意: Keyboard Layout Editor (KLE) や kbfirmware などの他のツールのファイルは、QMK Configurator と互換性がありません。それらをロードしたり、インポートしたりしないでください。QMK Configurator は異なるツールです。** + +[QMK Configurator: ステップ・バイ・ステップ](ja/configurator_step_by_step.md)を参照してください。 diff --git a/ja/newbs_flashing.md b/ja/newbs_flashing.md new file mode 100644 index 00000000000..3e1529706e6 --- /dev/null +++ b/ja/newbs_flashing.md @@ -0,0 +1,127 @@ +# ファームウェアを書きこむ + + + +カスタムファームウェアは出来たので、キーボードに書き込みたくなるでしょう/フラッシュしたくなるでしょう。 + +## キーボードを DFU (Bootloader) モードにする + +カスタムファームウェアを書き込むには、最初にキーボードを普段とは違う特別な状態、フラッシュモードにする必要があります。 +このモードでは、キーボードはキーボードとしての機能を果たしません。 +ファームウェアの書き込み中にキーボードのケーブルを抜いたり、書き込みプロセスを中断したりしないことが非常に重要です。 + +キーボードによって、この特別なモードに入る方法は異なります。 +PCB が現在 QMK、TMK、PS2AVRGB (Bootmapper Client) を実行しており、キーボードメーカーから具体的な指示が与えられていない場合は、次を順番に試してください。 + +* 両方のシフトキーを押しながら、`Pause` キーを押す +* 両方のシフトキーを押しながら、`B` キーを押す +* キーボードのケーブルを抜いて、スペースバーと `B` を同時に押しながら、キーボードを再び接続し、1秒待ってからキーを放す +* キーボードのケーブルを抜いて、左上か左下のキー(通常は Escape か左 Control)を押しながらキーボードを接続する +* 通常、PCB の裏側に付けられている物理的な `RESET` ボタンを押す +* PCB 上の `RESET` か `GND` のラベルの付いたヘッダピンを探し、PCB 接続中にそれらを互いにショートする + +上記を全て試してもうまくいかず、基板のメインチップに `STM32` と表示されている場合、これは少し複雑になる可能性があります。通常、最善の方法は [Discord](https://discord.gg/Uq7gcHh) で助けを求めることです。おそらく基板の写真をいくつか求められるでしょう。あらかじめそれらを準備することができれば物事を進めるのに役立ちます! + +それ以外の場合は、QMK Toolbox で次のような黄色のメッセージが表示されます: + +``` +*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) +``` + +そして、このブートローダデバイスはデバイスマネージャーやシステム情報.app、`lsusb` にも表示されます。 + +## QMK Toolbox を使ってキーボードに書き込む + +キーボードに書き込む最も簡単な方法は [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) を使うことです。 + +ただし、QMK Toolbox は、現在は Windows と macOS でしか使えません。 +Linux を使用している場合(および、コマンドラインでファームウェアを書き込みたい場合)は、[コマンドラインからキーボードを書き込む](#flash-your-keyboard-from-the-command-line)節まで進んでください。 + +### QMK Toolbox にファイルをロードする + +まず QMK Toolbox アプリケーションを起動します。 +Finder またはエクスプローラーでファームウェアのファイルを探します。 +キーボードのファームウェアは `.hex` または `.bin` のどちらかの形式です。 +ビルド時に QMK は、キーボードに適した形式のものを `qmk_firmware` のトップフォルダにコピーしているはずです。 + +Windows か macOS を使用している場合、現在のフォルダをエクスプローラーか Finder で簡単に開くためのコマンドがあります。 + +#### Windows + +``` +start . +``` + +#### macOS + +``` +open . +``` + +ファームウェアファイルは常に以下の命名形式に従っています: + +``` +_.{bin,hex} +``` + +例えば、`plank/rev5` の `default` キーマップのファイル名は以下のようになります: + +``` +planck_rev5_default.hex +``` + +ファームウェアファイルを見つけたら、QMK Toolbox の "Local file" ボックスにドラッグするか、"Open" をクリックしてファームウェアファイルが格納されている場所を指定します。 + +### キーボードへの書き込み + +QMK Toolbox の `Flash` ボタンをクリックします。次のような出力が表示されます。 + +``` +*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) +*** Attempting to flash, please don't remove device +>>> dfu-programmer.exe atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer.exe atmega32u4 flash "D:\Git\qmk_firmware\gh60_satan_default.hex" + Checking memory from 0x0 to 0x3F7F... Empty. + 0% 100% Programming 0x3F80 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x3F80 bytes written into 0x7000 bytes memory (56.70%). +>>> dfu-programmer.exe atmega32u4 reset + +*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000) +``` + +## コマンドラインでファームウェアを書き込む :id=flash-your-keyboard-from-the-command-line + +これは、以前のものと比較して非常に単純になりました。 +ファームウェアをコンパイルして書き込む準備ができたら、ターミナルウィンドウを開いて書き込みコマンドを実行します: + + qmk flash + +もし CLI でキーボードやキーマップ名を設定していない場合や、複数のキーボードを持っている場合、キーボードとキーマップを指定することができます: + + qmk flash -kb -km + +これはキーボードの設定を確認し、指定されたブートローダに基づいて書き込もうとします。これはどのブートローダをキーボードが使っているか知る必要がないことを意味します。単にコマンドを実行し、コマンドに重い仕事をさせましょう。 + +ただし、これはキーボードごとに設定されているブートローダに依存します。 +もし、この情報が設定されていない場合、または、使用しているキーボードが、ファームウェア書き込みでサポートされているターゲットを持っていない場合、次のエラーが表示されます: + + WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. + +この場合、あなたは明示的にブートローダを指定する方法を使わなければなりません。詳細は、[ファームウェアのフラッシュ](ja/flashing.md) ガイドを参照してください。 + +## テストしましょう! + +おめでとうございます! カスタムファームウェアがキーボードにプログラムされました! + +使ってみて、すべてがあなたの望むように動作するかどうか確認してください。 +この初心者ガイドを完全なものにするために [テストとデバッグ](ja/newbs_testing_debugging.md) を書いたので、ファームウェアの検証とカスタム機能のトラブルシューティング方法について学ぶには、こちらをご覧ください。 diff --git a/ja/newbs_getting_started.md b/ja/newbs_getting_started.md new file mode 100644 index 00000000000..05608bf874c --- /dev/null +++ b/ja/newbs_getting_started.md @@ -0,0 +1,156 @@ +# QMK 環境の構築 + + + +キーマップをビルドする前に、いくつかのソフトウェアをインストールしてビルド環境を構築する必要があります。 +ファームウェアをコンパイルするキーボードの数に関わらず、この作業を一度だけ実行する必要があります。 + +## 1. ソフトウェアのダウンロード + +始めるために必要なソフトウェアがいくつかあります。 + +### テキストエディタ + +**プレーンテキスト** ファイルを編集して保存できるプログラムが必要です。 +Windows の場合、メモ帳が使えます。Linux の場合、gedit が使えます。どちらもシンプルですが機能的なテキストエディタです。 +macOS では、デフォルトのテキストエディットアプリに注意してください。_フォーマット_ メニューから _標準テキストにする_ を選択しない限り、プレーンテキストとして保存されません。 + +[Sublime Text](https://www.sublimetext.com/) や [VS Code](https://code.visualstudio.com/) のような専用のテキストエディタをダウンロードしてインストールすることもできます。これらのプログラムはコードを編集するために特別に作成されているため、これはプラットフォームに関係なくベストな方法です。 + +?> どのエディタを使えば良いか分からない場合、Laurence Bradford が書いたこの記事 [a great introduction](https://learntocodewith.me/programming/basics/text-editors/) を読んでください。 + +### QMK Toolbox + +QMK Toolbox は、Windows と macOS で使える GUI を備えたプログラムで、カスタムキーボードのプログラミングとデバッグの両方ができます。 +このプログラムは、キーボードに簡単にファームウェアを書き込んだり、出力されるデバッグメッセージを確認する際に、かけがえのないものであることがわかるでしょう。 + +[QMK Toolbox の最新版](https://github.com/qmk/qmk_toolbox/releases/latest) + +* Windows 版: `qmk_toolbox.exe` (portable) または `qmk_toolbox_install.exe` (installer) +* macOS 版: `QMK.Toolbox.app.zip` (portable) または `QMK.Toolbox.pkg` (installer) + +### Unix ライクな環境 + +Linux や macOS には既に実行可能な unix シェルが付属しています。ビルド環境を構築するだけで済みます。 + +Windows では、MSYS2 や WSL をインストールして、これらの環境を使う必要があります。MSYS2 の構築手順を以下に示します。 + +## 2. ビルド環境を準備する :id=set-up-your-environment + +私たちは、QMK を可能な限り簡単に構築できるように努力しています。 +Linux か Unix 環境を用意するだけで、QMK に残りをインストールさせることができます。 + +?> もし、Linux か Unix のコマンドを使ったことがない場合、こちらで基本的な概念や各種コマンドを学んでください。これらの教材で QMK を使うのに必要なことを学ぶことができます:
+[Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
+[Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +MSYS2 と Git と QMK CLI のインストールが必要です。 + +[MSYS2 homepage](http://www.msys2.org) のインストール手順に従ってください。開いている MSYS2 の全ターミナル画面を閉じて、新しい MinGW 64-bit ターミナル画面を開きます。**注意: これはインストールが完了した時に開く MSYS ターミナルと同じ *ではありません*。** + +それから、次のように実行します: + + pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip + python3 -m pip install qmk + +### macOS + +Homebrew のインストールが必要です。[Homebrew homepage](https://brew.sh) の手順に従ってください。 + +Homebrew をインストールした後で、以下のコマンドを実行します: + + brew install qmk/qmk/qmk + +### Linux + +Git と Python をインストールする必要があります。両方とも既にインストールされている可能性は高いですが、そうでない場合、次のコマンドのいずれかでそれらをインストールできます: + +* Debian / Ubuntu / Devuan: `sudo apt install git python3 python3-pip` +* Fedora / Red Hat / CentOS: `sudo yum install git python3 python3-pip` +* Arch / Manjaro: `sudo pacman -S git python python-pip python-setuptools libffi` + +グローバル CLI をインストールして、システムをブートストラップします: + +`python3 -m pip install --user qmk` (Arch ベースのディストリビューションでは AUR から `qmk` パッケージを試すこともできます(**メモ**: コミュニティメンバーによって保守されています): `yay -S qmk`) + +### FreeBSD + +Git と Python をインストールする必要があります。両方とも既にインストールされている可能性は高いですが、そうでない場合、次のコマンドを実行してそれらをインストールします: + + pkg install git python3 + +ローカルにインストールした Python パッケージが利用できるように、`$HOME/.local/bin` が `$PATH` に追加されていることを確認してください。 + +インストール完了後、QMK CLI をインストールできます: + + python3 -m pip install --user qmk + +## 3. QMK の設定を行う :id=set-up-qmk + +QMK のインストール後に、このコマンドで設定できます: + + qmk setup + +ほとんどの場合、全てのプロンプトに Yes と答えます。 + +?>**Debian、Ubuntu、それらの派生に関する注意**: +次のようなエラーが表示される可能性があります: `bash: qmk: command not found`. +これは Debian の Bash 4.4 リリースで導入された [バグ](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155) で、`$HOME/.local/bin` が PATH から削除されました。このバグは後に Debian や Ubuntu で修正されました。 +残念なことに、Ubuntu はこのバグを再導入し、[まだ修正していません](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562)。 +幸い、修正は簡単です。これをあなたのユーザで実行します: `echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc` + +?>**FreeBSD に関する注意**: +まず、`root` 以外のユーザで `qmk setup` を実行することをお勧めしますが、これはおそらく `pkg` を使って基本システムにインストールする必要があるパッケージを識別します。 +しかし、特権のないユーザで実行すると、インストールはおそらく失敗します。 +基本的な依存関係を手動でインストールするには、`./util/qmk_install.sh` を `root` として実行するか、`sudo` をつけて実行します。 +それが完了したら、`qmk setup` を再実行して設定と確認を完了させます。 + +?> 既に [GitHub の使いかた](ja/getting_started_github.md)を知っているなら、fork を作成し、`qmk setup /qmk_firmware` を使って個人用の fork から clone することをお勧めします。この一文の意味が分からない場合、このメッセージは無視してかまいません。 + +## 4. ビルド環境の確認 + +これで QMK のビルド環境が用意できたので、キーボードのファームウェアをビルドできます。 +キーボードのデフォルトキーマップをビルドすることから始めます。次の形式のコマンドでビルドできるはずです。 + + qmk compile -kb -km default + +例えば、Clueboard 66% のファームウェアをビルドする場合: + + qmk compile -kb clueboard/66/rev3 -km default + +大量の出力の最後に次のように出力されると完了です: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +## 5. ビルド環境の設定(オプション) + +ビルド環境を設定してデフォルトを設定することで、QMK での作業をあまり面倒くさくないようにすることができます。今からやりましょう! + +QMK を初めて使うほとんどの人は、キーボードを1つしか持っていません。`qmk config` コマンドでこのキーボードをデフォルトとして設定できます。例えば、デフォルトのキーボードを `clueboard/66/rev4` に設定するには: + + qmk config user.keyboard=clueboard/66/rev4 + +デフォルトキーマップ名を設定することもできます。ほとんどの人はここで GitHub ユーザ名を使いますが、そうすることをお勧めします。 + + qmk config user.keymap= + +この後、これらの引数をオフにして、次のようにキーボードをコンパイルできます: + + qmk compile + +# キーマップの作成 + +これであなた専用のキーマップを作成する準備ができました! +次は [初めてのファームウェアの構築](ja/newbs_building_firmware.md) で専用のキーマップを作成します。 diff --git a/ja/newbs_git_best_practices.md b/ja/newbs_git_best_practices.md new file mode 100644 index 00000000000..7ba16fce751 --- /dev/null +++ b/ja/newbs_git_best_practices.md @@ -0,0 +1,24 @@ +# QMK における Git 運用作法 :id=best-git-practices-for-working-with-qmk + + + +## または、"如何にして私は心配することをやめて Git を愛することを学んだか。" + +このセクションは、QMK への貢献をスムーズに行なう最もよい方法を初心者に教えることを目的としています。 +QMK に貢献するプロセスを順を追って説明し、この作業を簡単にするいくつかの方法を詳しく説明します。 +その後、意図的に一部を壊してみせて、それらを修正する方法を説明します。 + +このセクションは以下のことを前提としています: + +1. あなたは GitHub アカウントがあり、アカウントに [qmk_firmware リポジトリをフォーク](ja/getting_started_github.md) している。 +2. あなたは、[環境構築](ja/newbs_getting_started.md#set-up-your-environment) と [QMK の設定](ja/newbs_getting_started.md#set-up-qmk) を両方とも完了している。 + +--- + +- パート 1: [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) +- パート 2: [マージの競合の解決](ja/newbs_git_resolving_merge_conflicts.md) +- パート 3: [同期のとれていない git ブランチの再同期](ja/newbs_git_resynchronize_a_branch.md) diff --git a/ja/newbs_git_resolving_merge_conflicts.md b/ja/newbs_git_resolving_merge_conflicts.md new file mode 100644 index 00000000000..532b1e30019 --- /dev/null +++ b/ja/newbs_git_resolving_merge_conflicts.md @@ -0,0 +1,94 @@ +# マージの競合の解決 + + + +ブランチでの作業の完了に時間がかかる場合、他の人が行った変更が、プルリクエストを開いたときにブランチに加えた変更と競合することがあります。 +これは *マージの競合* と呼ばれ、複数の人が同じファイルの同じ部分を編集すると発生します。 + +?> このドキュメントは [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) で詳述されている概念に基づいています。 +その概念に慣れていない場合は、まずそれを読んでから、ここに戻ってください。 + +## 変更のリベース + +*リベース* は、コミット履歴のある時点で適用された変更を取得し、それらを元に戻し、次に同じ変更を別のポイントに適用する Git の方法です。 +マージの競合が発生した場合、ブランチをリベースして、ブランチを作成してから現在までに行われた変更を取得できます。 + +開始するには、次を実行します: + +``` +git fetch upstream +git rev-list --left-right --count HEAD...upstream/master +``` + +ここに入力された `git rev-list` コマンドは、現在のブランチと QMK の master ブランチで異なるコミットの数を返します。 +最初に `git fetch` を実行して、upstream リポジトリの現在の状態を表す refs があることを確認します。 +入力された `git rev-list` コマンドの出力は2つの数値を返します: + +``` +$ git rev-list --left-right --count HEAD...upstream/master +7 35 +``` + +最初の数字は、現在のブランチが作成されてからのコミット数を表し、2番目の数字は、現在のブランチが作成されてから `upstream/master` に対して行われたコミットの数であり、したがって、現在のブランチに記録されていない変更です。 + +現在のブランチと upstream リポジトリの両方の現在の状態がわかったので、リベース操作を開始できます: + +``` +git rebase upstream/master +``` + +これにより、Git は現在のブランチのコミットを取り消してから、QMK の master ブランチに対してコミットを再適用します。 + +``` +$ git rebase upstream/master +First, rewinding head to replay your work on top of it... +Applying: Commit #1 +Using index info to reconstruct a base tree... +M conflicting_file_1.txt +Falling back to patching base and 3-way merge... +Auto-merging conflicting_file_1.txt +CONFLICT (content): Merge conflict in conflicting_file_1.txt +error: Failed to merge in the changes. +hint: Use 'git am --show-current-patch' to see the failed patch +Patch failed at 0001 Commit #1 + +Resolve all conflicts manually, mark them as resolved with +"git add/rm ", then run "git rebase --continue". +You can instead skip this commit: run "git rebase --skip". +To abort and get back to the state before "git rebase", run "git rebase --abort". +``` + +これにより、マージの競合があることがわかり、競合のあるファイルの名前が示されます。 +テキストエディタで競合するファイルを開くと、ファイルのどこかに次のような行があります: + +``` +<<<<<<< HEAD +

For help with any issues, email us at support@webhost.us.

+======= +

Need help? Email support@webhost.us.

+>>>>>>> Commit #1 +``` + +行 `<<<<<<< HEAD` はマージ競合の始まりを示し、行 `>>>>>>> commit #1` は終了を示し、競合するセクションは `=======` で区切られます。 +`HEAD` 側の部分はファイルの QMK master バージョンからのものであり、コミットメッセージでマークされた部分は現在のブランチとコミットからのものです。 + +Git はファイルの内容ではなく *ファイルへの変更* を直接追跡するため、Git がコミットの前にファイル内にあったテキストを見つけられない場合、ファイルの編集方法がわかりません。 +ファイルを再編集して、競合を解決します。 +変更を加えてから、ファイルを保存します。 + +``` +

Need help? Email support@webhost.us.

+``` + +そしてコマンド実行: + +``` +git add conflicting_file_1.txt +git rebase --continue +``` + +Git は、競合するファイルへの変更をログに記録し、ブランチのコミットが最後に達するまで適用し続けます。 diff --git a/ja/newbs_git_resynchronize_a_branch.md b/ja/newbs_git_resynchronize_a_branch.md new file mode 100644 index 00000000000..567ec38bfec --- /dev/null +++ b/ja/newbs_git_resynchronize_a_branch.md @@ -0,0 +1,88 @@ +# 同期のとれていない git ブランチの再同期 + + + +仮にあなたの `master` ブランチにあなたのコミットを行い、そしてあなたの QMK リポジトリの更新が必要になったとします。 +(フォーク元の) QMK の `master` ブランチをあなたの `master` ブランチに `git pull` することもできますが、GitHub は、あなたのブランチが `qmk:master` より何コミットか先行していると通知します、この状態で QMK にプルリクエストを行う場合、問題が発生する可能性があります。 +(訳注:この通知は、GitHub のあなたのリポジトリの code ペインのブランチ選択メニューの下のあたりで `This branch is 3 commit ahead of qmk:master` という様な文面で表示されています。) + +?> このドキュメントは [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) で詳述されている概念に基づいています。その概念に慣れていない場合は、まずそれを読んでから、ここに戻ってください。 +(訳注:この文書で言う、「同期のとれていない git ブランチ」とは、master ブランチに関する、この「コミットしない」方針を逸脱して、QMK の master リポジトリに存在しないコミットがあなたのフォークの master ブランチに入っている状態を指します。) + +## あなた自身の `master` ブランチでの変更のバックアップ(オプション) + +救えるものなら自分の行った変更を失いたくはないでしょう。 +あなたの `master` ブランチに既に加えた変更を保存したい場合、最も簡単な方法は、単に「ダーティな」`master` ブランチの複製を作成することです: + +```sh +git branch old_master master +``` + +これで、 `master` ブランチの複製である `old_master` という名前のブランチができました。 + +## あなたのブランチの再同期 + +さあ、`master` ブランチを再同期します。 +この手順では、QMK のリポジトリを git のリモートリポジトリとして設定する必要があります。 +設定済みのリモートリポジトリを確認するには、`git remote -v` を実行し、次のような結果が返されなければなりません。 + +```sh +QMKuser ~/qmk_firmware (master) +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +もし、上記のようにならずに以下のように参照されるフォークが、1つだけ表示される場合: + +```sh +QMKuser ~/qmk_firmware (master) +$ git remote -v +origin https://github.com/qmk/qmk_firmware.git (fetch) +origin https://github.com/qmk/qmk_firmware.git (push) +``` + +新しいリモートリポジトリを追加します: + +```sh +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +次に、`origin` リモートリポジトリを、あなた自身のフォークにリダイレクトします: + +```sh +git remote set-url origin https://github.com/<あなたのユーザ名>/qmk_firmware.git +``` + +両方のリモートリポジトリが設定されたので、次を実行して、QMK である `upstream` リポジトリの参照を更新する必要があります。 + +```sh +git fetch upstream +``` + +この時点で、次を実行してあなたの(訳注:master)ブランチを QMK のブランチに再同期します。 +(訳注: 今現在 `master` ブランチがチェックアウトされていなければなりません。 + そうなってなければ、`git checkout master` を先に実行しておく必要があります。) + +```sh +git reset --hard upstream/master +``` + +これらの手順により、あなたのコンピュータ上のリポジトリが更新されますが、あなたの GitHub 上のフォークはまだ同期されていません。 +GitHub 上のフォークを再同期するには、あなたのフォークにプッシュして、ローカルリポジトリに反映されていないリモート変更をオーバーライドするように Git に指示する必要があります。 +これを行うには、次を実行します: + +```sh +git push --force-with-lease +``` + +!> 他のユーザーがコミットを投稿するフォークで `git push --force-with-lease` を**実行しないでください**。これをすると、かれらのコミットが消去されてしまいます。 + +これで、あなたの GitHub フォーク、あなたのローカルファイル、および QMK のリポジトリはすべて同じになりました。 +ここから、[ブランチを使って](ja/newbs_git_using_your_master_branch.md#making-changes)さらに必要な変更を加え、通常どおりそれらを投稿できます。 diff --git a/ja/newbs_git_using_your_master_branch.md b/ja/newbs_git_using_your_master_branch.md new file mode 100644 index 00000000000..308a61eded1 --- /dev/null +++ b/ja/newbs_git_using_your_master_branch.md @@ -0,0 +1,101 @@ +# あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと + + + +QMK の開発では、何がどこで行われているかにかかわらず、`master` ブランチを最新の状態に保つことを強くお勧めします、しかし `master` ブランチには***絶対に直接コミットしないでください***。 +代わりに、あなたのすべての変更は開発ブランチで行い、あなたが開発する時にはそのブランチからプルリクエストを発行します。 + +マージの競合 — これは 2人以上のユーザーがファイルの同じ部分をそれぞれ異なる編集をして統合できなくなった状態 — の可能性を減らすため `master` ブランチをなるべく最新の状態に保ち、新しいブランチを作成して新しい開発を開始します。 + +## あなたの master ブランチを更新する + +`master` ブランチを最新の状態に保つには、git のリモートリポジトリとして QMK ファームウェアのリポジトリ(以降、QMK リポジトリ)を追加することをお勧めします。 +これを行うには、Git コマンドラインインターフェイスを開き、次のように入力します。 + +``` +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +?> `upstream`(訳注: `upstream` は`上流`という意味です)という名前は任意ですが、一般的な慣習です。 +QMK のリモートリポジトリには、あなたにとって分かりやすい名前を付けることができます。 +Git の `remote` コマンドは、構文 `git remote add ` を使用します。 +`` はリモートリポジトリの省略形としてあなたが指定するものです。 +この名前は、`fetch`、`pull`、`push` やそれ以外の多くの Git コマンドで、対象のリモートリポジトリを指定するために使用されます。 + +リポジトリが追加されたことを確認するには、`git remote -v` を実行します。 +次のように表示されます。 + +``` +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +これが完了すると、`git fetch upstream` を実行してリポジトリの更新を確認できます。 +このコマンドは `upstream` というニックネームを持つ QMK リポジトリから、ブランチとタグ — "refs" と総称されます — を取得します。 +これで、あなたのフォーク `origin` のデータを QMK が保持するデータと比較できます。 + +あなたのフォークの `master` を更新するには、次を実行します、各行の後に Enter キーを押してください: + +``` +git checkout master +git fetch upstream +git pull upstream master +git push origin master +``` + +これにより、あなたの `master` ブランチに切り替わり、QMK リポジトリから 'refs' を取得し、現在の QMK の `master` ブランチをコンピュータにダウンロードしてから、あなたのフォークにアップロードします。 + +## 変更を行なう :id=making-changes + +変更するには、以下を入力して新しいブランチを作成します: + +``` +git checkout -b dev_branch +git push --set-upstream origin dev_branch +``` + +これにより、`dev_branch` という名前の新しいブランチが作成され、チェックアウトされ、新しいブランチがあなたのフォークに保存されます。 +`--set-upstream` 引数は、このブランチから `git push` または `git pull` を使用するたびに、あなたのフォークと `dev_branch` ブランチを使用するように git に指示します。 +この引数は最初のプッシュでのみ使用する必要があります。 +その後、残りの引数なしで `git push` または `git pull` を安全に使用できます。 + +?> `git push` では、`-set-upstream` の代わりに `-u` を使用できます、 `-u` は `--set-upstream` のエイリアスです。 + +ブランチにはほぼ任意の名前を付けることができますが、あなたが行なう変更を表す名前を付けることをお勧めします。 + +デフォルトでは、`git checkout -b`は、今チェックアウトされているブランチに基づいて新しいブランチを作成します。 +コマンド末尾に既存のブランチの名前を追加指定することにより、チェックアウトされていない既存のブランチを基にして新しいブランチを作成できます: + +``` +git checkout -b dev_branch master +``` + +これで開発ブランチができたのでテキストエディタを開き必要な変更を加えます。 +ブランチに対して多くの小さなコミットを行うことをお勧めします。 +そうすることで、問題を引き起こす変更をより簡単に特定し必要に応じて元に戻すことができます。 +変更を加えるには、更新が必要なファイルを編集して保存し、Git の *ステージングエリア* に追加してから、ブランチにコミットします: + +``` +git add path/to/updated_file +git commit -m "My commit message." +``` + +`git add`は、変更されたファイルを Git の *ステージングエリア* に追加します。 +これは、Git の「ロードゾーン」です。 +これには、`git commit` によって *コミット* される変更が含まれており、リポジトリへの変更が保存されます。 +変更内容が一目でわかるように、説明的なコミットメッセージを使用します。 + +?> 複数のファイルを変更した場合、`git add -- path/to/file1 path/to/file2 ...` を実行すれば、あなたの望むファイルを追加できます。 + +## 変更を公開する + +最後のステップは、変更をフォークにプッシュすることです。 +これを行うには、`git push`と入力します。 +Git は、 `dev_branch`の現在の状態をフォークに公開します。 diff --git a/ja/newbs_learn_more_resources.md b/ja/newbs_learn_more_resources.md new file mode 100644 index 00000000000..e5437ca86af --- /dev/null +++ b/ja/newbs_learn_more_resources.md @@ -0,0 +1,45 @@ +# 学習リソース + + + +これらのリソースは、QMK コミュニティの新しいメンバーに、初心者向けドキュメントで提供されている情報に対する理解を深めることを目的としています。 + +## QMK に関するリソース: + +### 英語 :id=english-resources-qmk + +* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 新規ユーザーの視点から見た QMK ファームウェアの使い方の基本を網羅した、ユーザー作成のブログ。 + +### 日本語 :id=japanese-resources-qmk + +_日本語のリソース情報を募集中です。_ + +## コマンドラインに関するリソース: + +### 英語 :id=english-resources-cli + +* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line) + +### 日本語 :id=japanese-resources-cli + +_日本語のリソース情報を募集中です。_ + +## Git に関するリソース: + +### 英語 :id=english-resources-git + +* [Great General Tutorial](https://www.codecademy.com/learn/learn-git) +* [Flight Rules For Git](https://github.com/k88hudson/git-flight-rules) +* [Git Game To Learn From Examples](https://learngitbranching.js.org/) + +### 日本語 :id=japanese-resources-git + +_日本語のリソース情報を募集中です。_ + +* [Git Game To Learn From Examples(日本語対応有り)](https://learngitbranching.js.org/) + git のブランチの作り方、マージの仕方などがビジュアルに学べます。 +* [QMK で GitHub を使う方法](ja/getting_started_github.md) diff --git a/ja/newbs_testing_debugging.md b/ja/newbs_testing_debugging.md new file mode 100644 index 00000000000..b80e09fc700 --- /dev/null +++ b/ja/newbs_testing_debugging.md @@ -0,0 +1,104 @@ +# テストとデバッグ + + + +カスタムファームウェアをキーボードへ書き込んだら、テストする準備が整います。運が良ければ全て問題なく動作しているはずですが、もしそうでなければこのドキュメントがどこが悪いのか調べるのに役立ちます。 + +## テスト + +通常、キーボードをテストするのは非常に簡単です。 +全てのキーをひとつずつ押して、期待されるキーが送信されていることを確認します。 +QMK を実行していなくても、[QMK Configurator](https://config.qmk.fm/#/test/) のテストモードを使ってキーボードを確認することができます。 + +## デバッグ :id=debugging + +`rules.mk`へ`CONSOLE_ENABLE = yes`の設定をするとキーボードはデバッグ情報を出力します。デフォルトの出力は非常に限られたものですが、デバッグモードをオンにすることでデバッグ情報の量を増やすことが出来ます。キーマップの`DEBUG`キーコードを使用するか、デバッグモードを有効にする [コマンド](ja/feature_command.md) 機能を使用するか、以下のコードをキーマップに追加します。 + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + +## デバッグツール :id=debugging-tools + +キーボードのデバッグに使えるツールは2つあります。 + +### QMK Toolboxを使ったデバッグ + +互換性のある環境では、[QMK Toolbox](https://github.com/qmk/qmk_toolbox)を使うことでキーボードからのデバッグメッセージを表示できます。 + +### hid_listenを使ったデバッグ + +ターミナルベースの方法がお好みですか?PJRC が提供する[hid_listen](https://www.pjrc.com/teensy/hid_listen.html)もデバッグメッセージの表示に使用できます。ビルド済みの実行ファイルは Windows, Linux, MacOS 用が用意されています。 + + +## 独自のデバッグメッセージを送信する + +[custom code](ja/custom_quantum_functions.md)内からデバッグメッセージを出力すると便利な場合があります。それはとても簡単です。ファイルの先頭に`print.h`のインクルードを追加します: + + #include + +そのあとは、いくつかの異なった print 関数を使用することが出来ます。 + +* `print("string")`: シンプルな文字列を出力します +* `uprintf("%s string", var)`: フォーマットされた文字列を出力します +* `dprint("string")` デバッグモードが有効な場合のみ、シンプルな文字列を出力します +* `dprintf("%s string", var)`: デバッグモードが有効な場合のみ、フォーマットされた文字列を出力します + +## デバッグの例 + +以下は現実世界での実際のデバッグ手法の例を集めたものです。追加情報は[Debugging/Troubleshooting QMK](ja/faq_debug.md)を参照してください。 + +### マトリックス上のどの場所でキー押下が起こったか? + +移植する、PCBの問題を診断する場合、キー入力が正しくスキャンされているかどうかを確認することが役立つ場合があります。この手法でのロギングを有効化するには、`keymap.c`へ以下のコードを追加します。 + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // コンソールが有効化されている場合、マトリックス上の位置とキー押下状態を出力します +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif + return true; +} +``` + +出力の例 +```text +Waiting for device:....... +Listening: +KL: kc: 169, col: 0, row: 0, pressed: 1 +KL: kc: 169, col: 0, row: 0, pressed: 0 +KL: kc: 174, col: 1, row: 0, pressed: 1 +KL: kc: 174, col: 1, row: 0, pressed: 0 +KL: kc: 172, col: 2, row: 0, pressed: 1 +KL: kc: 172, col: 2, row: 0, pressed: 0 +``` + +### キースキャンにかかる時間の測定 + +パフォーマンスの問題をテストする場合、スイッチマトリックスをスキャンする頻度を知ることが役立ちます。この手法でのロギングを有効化するには`config.h`へ以下のコードを追加します。 + + +```c +#define DEBUG_MATRIX_SCAN_RATE +``` + +出力例 +```text + > matrix scan frequency: 315 + > matrix scan frequency: 313 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 +``` diff --git a/ja/one_shot_keys.md b/ja/one_shot_keys.md new file mode 100644 index 00000000000..61cf31beffd --- /dev/null +++ b/ja/one_shot_keys.md @@ -0,0 +1,107 @@ +# ワンショットキー + + + +ワンショットキーは次のキーが押されるまでアクティブのままになり、そのあと放されるキーです。これにより一度に1つ以上のキーを押すことなく、キーボードの組み合わせを入力することができます。これらのキーは通常「スティッキーキー」あるいは「デッドキー」と呼ばれます。 + +例えば、キーを `OSM(MOD_LSFT)` と定義する場合、最初にシフトを押して放し、続いて A を押して放すことで、大文字の A キャラクタを入力することができます。コンピュータには、シフトが押された瞬間にシフトが押し続けられ、A が放された後ですぐにシフトキーが放されるように見えます。 + +ワンショットキーは通常のモディファイアのようにも動作します。ワンショットキーを押しながら他のキーを入力すると、キーを放した直後にワンショットキーが解除されます。 + +さらに、短時間でキーを5回押すと、そのキーをロックします。これはワンショットモディファイアとワンショットレイヤーに適用され、`ONESHOT_TAP_TOGGLE` 定義によって制御されます。 + +`config.h` でこれらを定義することでワンショットキーの挙動を制御することができます: + +```c +#define ONESHOT_TAP_TOGGLE 5 /* この回数をタップすると、もう一度タップするまでキーが押されたままになります。*/ +#define ONESHOT_TIMEOUT 5000 /* ワンショットキーが解除されるまでの時間 (ms) */ +``` + +* `OSM(mod)` - *mod*を一時的に押し続けます。[モッドタップ](ja/mod_tap.md)で示したように、`KC_*` コードでは無く、`MOD_*` キーコードを使わなければなりません。 +* `OSL(layer)` - 一時的に*レイヤー*に切り替えます。 + +ワンショットキーをマクロあるいはタップダンスルーチンの一部として有効にしたい場合があります。 + +ワンショットレイヤーについては、キーを押した時に `set_oneshot_layer(LAYER, ONESHOT_START)` を呼び出し、キーを放した時に `clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED)` を呼び出す必要があります。ワンショットをキャンセルする場合は、`reset_oneshot_layer()` を呼び出してください。 + +ワンショットモッドについては、設定するためには `set_oneshot_mods(MOD)` を呼び出し、キャンセルするためには `clear_oneshot_mods()` を呼び出す必要があります。 + +!> リモートデスクトップ接続で OSM 変換に問題がある場合は、設定を開いて「ローカル リソース」タブに移動し、キーボードセクションでドロップダウンを「このコンピューター」に変更することで修正することができます。これにより問題が修正され、OSM がリモートデスクトップ上で適切に動作するようになります。 + +## コールバック + +ワンショットキーを押す時にカスタムロジックを実行したい場合、実装を選択できる幾つかのコールバックがあります。例えば、LED を点滅させたり、音を鳴らしたりして、ワンショットキーの変化を示すことができます。 + +`OSM(mod)` のためのコールバックがあります。ワンショット修飾キーの状態が変更されるたびに呼び出されます: オンに切り替わる時だけでなく、オフに切り替わる時にも呼び出されます。以下のように使うことができます: + +```c +void oneshot_mods_changed_user(uint8_t mods) { + if (mods & MOD_MASK_SHIFT) { + println("Oneshot mods SHIFT"); + } + if (mods & MOD_MASK_CTRL) { + println("Oneshot mods CTRL"); + } + if (mods & MOD_MASK_ALT) { + println("Oneshot mods ALT"); + } + if (mods & MOD_MASK_GUI) { + println("Oneshot mods GUI"); + } + if (!mods) { + println("Oneshot mods off"); + } +} +``` + +`mods` 引数は変更後のアクティブな mod が含まれるため、現在の状態が反映されます。 + +(`config.h` に `#define ONESHOT_TAP_TOGGLE 2` を追加して) ワンショットタップトグルを使う場合、指定された回数だけ修飾キーを押してロックすることができます。そのためのコールバックもあります: + +```c +void oneshot_locked_mods_changed_user(uint8_t mods) { + if (mods & MOD_MASK_SHIFT) { + println("Oneshot locked mods SHIFT"); + } + if (mods & MOD_MASK_CTRL) { + println("Oneshot locked mods CTRL"); + } + if (mods & MOD_MASK_ALT) { + println("Oneshot locked mods ALT"); + } + if (mods & MOD_MASK_GUI) { + println("Oneshot locked mods GUI"); + } + if (!mods) { + println("Oneshot locked mods off"); + } +} +``` + +最後に、`OSL(layer)` ワンショットキーのためのコールバックもあります: + +```c +void oneshot_layer_changed_user(uint8_t layer) { + if (layer == 1) { + println("Oneshot layer 1 on"); + } + if (!layer) { + println("Oneshot layer off"); + } +} +``` + +いずれかのワンショットレイヤーがオフの場合、`layer` は 0 になります。ワンショットレイヤーの変更では無く、レイヤーの変更で何かを実行したい場合は、`layer_state_set_user` は使用するのに良いコールバックです。 + +独自のキーボードを作成している場合、`_kb` と同等の機能もあります: + +```c +void oneshot_locked_mods_changed_kb(uint8_t mods); +void oneshot_mods_changed_kb(uint8_t mods); +void oneshot_layer_changed_kb(uint8_t layer); +``` + +他のコールバックと同様に、更にカスタマイズを可能にするために `_user` バージョンを呼ぶようにしてください。 diff --git a/ja/other_eclipse.md b/ja/other_eclipse.md new file mode 100644 index 00000000000..bb6902253bc --- /dev/null +++ b/ja/other_eclipse.md @@ -0,0 +1,93 @@ +# QMK 開発のための Eclipse セットアップ + + + +[Eclipse][1]は Java 開発のために広く使われているオープンソースの [統合開発環境](https://en.wikipedia.org/wiki/Integrated_development_environment) (IDE) ですが、他の言語および用途のためにカスタマイズできる拡張可能なプラグインシステムがあります。 + +Eclipse のような IDE の使用は、プレーンテキストエディタの使用よりも多くの利点をもたらします。例えば、次のような利点です。 +* インテリジェントなコード補完 +* コード内の便利なナビゲーション +* リファクタリングツール +* 自動ビルド (コマンドラインは不要) +* Git 用の GUI +* 静的なコード解析 +* デバッグ、コードフォーマット、呼び出し階層の表示などの多くのツール。 + +このページの目的は、AVR ソフトウェアの開発および QMK コードベースで作業するために、Eclipse をセットアップする方法を文章化することです。 + +このセットアップは現時点では Ubuntu 16.04 でのみテストされていることに注意してください。 + +# 前提条件 +## ビルド環境 +始める前に、チュートリアルの[セットアップ](ja/newbs_getting_started.md)のセクションに従う必要があります。特に、[`qmk compile` コマンド](ja/newbs_building_firmware.md#build-your-firmware)でファームウェアをビルドできなければなりません。 + +## Java +Eclipse は Java アプリケーションであるため、実行するには Java 8 以降をインストールする必要があります。JRE または JDK を選択できますが、Java 開発を行う場合は後者が役に立ちます。 + +# Eclipse とプラグインのインストール +Eclipse は用途に応じて[いくつかのフレーバー](http://www.eclipse.org/downloads/eclipse-packages/)で提供されます。AVR スタックを構成するパッケージは無いため、Eclipse CDT (C/C++ 開発ツール)から始め、必要なプラグインをインストールする必要があります。 + +## Eclipse CDT のダウンロードとインストール +システムに既に Eclipse CDT がある場合は、この手順をスキップできます。ただし、より良いサポートのために最新の状態に保つことをお勧めします。 + +別の Eclipse パッケージをインストールしている場合は、通常は[その上に CDT プラグインをインストール](https://eclipse.org/cdt/downloads.php)することができます。しかし、軽くして、作業中のプロジェクトに必要のないツールが乱雑にならないように、ゼロから再インストールすることをお勧めします。 + +インストールは非常に簡単です: [5 Steps to install Eclipse](https://eclipse.org/downloads/eclipse-packages/?show_instructions=TRUE) に従い、ステップ3で **Eclipse IDE for C/C++ Developers** を選択します。 + +あるいは、直接 [Eclipse IDE for C/C++ Developers をダウンロード](http://www.eclipse.org/downloads/eclipse-packages/)([現在のバージョンへの直接リンク](http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr))し、選択した場所にパッケージを解凍することもできます (これにより `eclipse` フォルダが作成されます)。 + +## 最初の起動 +インストールが完了したら、Launch ボタンをクリックします。(パッケージを手動で解凍した場合は、Eclipse をインストールしたフォルダを開き、`eclipse` 実行可能ファイルをダブルクリックします) + +Workspace 選択で入力を促された場合は、Eclipse メタデータと通常のプロジェクトを保持するディレクトリを選択します。**`qmk_firmware` ディレクトリを選択しないでください**。これはプロジェクトディレクトリになります。代わりに親フォルダを選択するか、(できれば空の)他のフォルダを選択します(まだ使用していない場合は、デフォルトで問題ありません)。 + +開始したら、右上の Workbench ボタンをクリックし、workbench ビューに切り替えます (下部に開始時のようこそ画面をスキップするためのチェックボックスもあります)。 + +## 必要なプラグインをインストール +注意: プラグインをインストールするごとに、Eclipse を再起動する必要はありません。全てのプラグインがインストールされたら単に1回再起動します。 + +### [The AVR Plugin](http://avr-eclipse.sourceforge.net/) +これは最も重要なプラグインで、Eclipse が AVR C コードを_理解_できるようになります。[更新サイトを使うための指示](http://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download#Update_Site)に従い、未署名コンテンツのセキュリティ警告に同意します。 + +### [ANSI Escape in Console](https://marketplace.eclipse.org/content/ansi-escape-console) +このプラグインは QMK makefile によって生成された色付きビルド出力を適切に表示するために必要です。 + +1. Help > Eclipse Marketplace… を開きます +2. _ANSI Escape in Console_ を検索します +3. プラグインの Install ボタンをクリックします +4. 指示に従い、未署名コンテンツのセキュリティ警告に再度同意します。 + +両方のプラグインがインストールされたら、プロンプトに従って Eclipse を再起動します。 + +# QMK 用の Eclipse の設定 +## プロジェクトのインポート +1. File > New > Makefile Project with Existing Code をクリックします +2. 次の画面で: +* _Existing Code Location_ としてリポジトリをクローンしたディレクトリを選択します。 +* (オプション) プロジェクトに別の名前を付けます¹ 例えば _QMK_ あるいは _Quantum_; +* _AVR-GCC Toolchain_ を選択します; +* 残りをそのままにして、Finish をクリックします + +![Eclipse での QMK のインポート](http://i.imgur.com/oHYR1yW.png) + +3. これでプロジェクトがロードされインデックスされます。左側の _Project Explorer_ から、簡単にファイルを参照できます。 + +¹ カスタム名でプロジェクトをインポートすると問題が発生するかもしれません。正しく動作しない場合は、デフォルトのプロジェクト名 (つまり、ディレクトリの名前、おそらく `qmk_firmware`) のままにしてみてください。 + +## キーボードのビルド +ここで、プロジェクトをクリーンし、選択したキーマップをビルドする make target を設定します。 + +1. 画面の右側で、Make Target タブを選択します +2. フォルダツリーを選択したキーボードまで展開します。例えば、`qmk_firmware/keyboards/ergodox` +3. キーボードフォルダを右クリックして、New… を選択します (あるいはフォルダを選択し、ツリーの上にある New Make Target アイコンをクリックします) +4. ビルド target の名前を選択します。例えば、_clean \_ +5. Make Target: これはコマンドラインからビルドする時に `make` に渡す引数です。target 名がこれらの引数と一致しない場合は、Same as target name のチェックを外し、正しい引数を入力します。例えば、`clean ` +6. 他のオプションはチェックしたままにして、OK をクリックします。これで、選択されたキーボードの下に、make target が表示されます。 +7. (オプション) target ツリーの上にある Hide Empty Folders アイコンボタンを、ビルド target だけが表示されるように切り替えます。 +8. 作成したビルド target をダブルクリックし、ビルドを起動します。 +9. 下部の Console ビューを選択し、実行中のビルドを眺めます。 + +[1]: https://en.wikipedia.org/wiki/Eclipse_(software) diff --git a/ja/other_vscode.md b/ja/other_vscode.md new file mode 100644 index 00000000000..e786b08f397 --- /dev/null +++ b/ja/other_vscode.md @@ -0,0 +1,122 @@ +# QMK 開発用の Visual Studio Code のセットアップ + + + +[Visual Studio Code](https://code.visualstudio.com/) (VS Code) は多くの異なるプログラミング言語をサポートするオープンソースのコードエディタです。 + +VS Code のようなフル機能のエディタの使用は、プレーンテキストエディタの使用よりも多くの利点をもたらします。例えば、次のような利点です。: +* インテリジェントなコード補完 +* コード内の便利なナビゲーション +* リファクタリングツール +* 自動ビルド (コマンドラインは不要) +* Git 用のグラフィカルなフロントエンド +* デバッグ、コードフォーマット、呼び出し階層の表示などの多くのツール + +このページの目的は、QMK ファームウェアを開発するために VS Code をセットアップする方法を文章化することです。 + +このガイドは Windows および Ubuntu 18.04 で必要な全てを構成する方法を説明します。 + +# VS Code のセットアップ +はじめに、全てのビルドツールをセットアップし、QMK ファームウェアをクローンする必要があります。まだ設定していない場合は、[セットアップ](ja/newbs_getting_started.md)に進んでください。 + +## Windows + +### 前提条件 + +* [Git for Windows](https://git-scm.com/download/win) (このリンクはインストーラを保存あるいは実行するように促します) + + 1. `Git LFS (Large File Support)` および `Check daily for Git for Windows updates` 以外の全てのオプションを無効にします。 + 2. デフォルトのエディタを `Use Visual Studio Code as Git's default editor` に設定します。 + 3. ここで使用すべきオプションなので、`Use Git from Git Bash only` オプションを選択します。 + 4. `Choosing HTTPS transport backend` については、どちらのオプションでも問題ありません。 + 5. `Checkout as-is, commit Unix-style line endings` オプションを選択します。QMK ファームウェアは Unix スタイルのコミットを使います。 + 6. 追加のオプションについては、デフォルトのオプションをそのままにします。 + + このソフトウェアは、VS Code での Git サポートに必要です。これを含めないことも可能ですが、これを使う方が簡単です。 + +* [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases) (オプション) + + このソフトウェアは、git 証明書、MFA、パーソナルアクセストークン生成のためのセキュアストレージを提供することで、Git のより良いサポートを提供します。 + + これは厳密には必要ありませんが、お勧めします。 + + +### VS Code のインストール + +1. [VS Code](https://code.visualstudio.com/) に進み、インストーラをダウンロードします +2. インストーラを実行します + +この項は非常に簡単です。ただし、正しく構成されていることを確認するために、しなければならない幾つかの設定があります。 + +### VS Code の設定 + +最初に、IntelliSense をセットアップする必要があります。これは厳密には必要ではありませんが、あなたの人生をずっと楽にします。これを行うには、QMK ファームウェアフォルダに `.vscode/c_cpp_properties.json` ファイルを作成する必要があります。これは全て手動で行うことができますが、ほとんどの作業は既に完了しています。 + +[このファイル](https://gist.github.com/drashna/48e2c49ce877be592a1650f91f8473e8) を取得して保存します。MSYS2 をデフォルトの場所にインストールしなかった、または WSL か LxSS を使っている場合、このファイルを編集する必要があります。 + +このファイルを保存したら、VS Code が既に実行中の場合はリロードする必要があります。 + +?> また、`.vscode` フォルダ に `extensions.json` および `settings.json` ファイルがあるはずです。 + + +次に、VSCode に統合ターミナルとして表示されるように、MSYS2 ウィンドウを設定します。これには多くの利点があります。ほとんどの場合で、エラー上で Ctrl + クリックするとこれらのファイルにジャンプできます。これによりデバッグがはるかに簡単になります。また、他のウィンドウへジャンプする必要が無いという点でも優れています。 + +1. ファイル > ユーザー設定 > > 設定 をクリックします。 +2. 右上の {} ボタンをクリックし、`settings.json` ファイルを開きます。 +3. ファイルの内容を以下のように設定します: + + ```json + { + "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", + "terminal.integrated.env.windows": { + "MSYSTEM": "MINGW64", + "CHERE_INVOKING": "1" + }, + "terminal.integrated.shellArgs.windows": [ + "--login" + ], + "terminal.integrated.cursorStyle": "line" + } + ``` + + ここに既に設定がある場合は、最初と最後の波括弧の間に全てを追加し、既存の設定を新しく追加された設定とカンマで区切ります。 + +?> MSYS2 を別のフォルダにインストールした場合は、`terminal.integrated.shell.windows` のパスをシステムの正しいパスに変更する必要があります。 + +4. Ctrl-` (Grave) を押して、ターミナルを起動するか、表示 > ターミナル (コマンド `workbench.action.terminal.toggleTerminal`)に進みます。まだターミナルが開いていない場合は、新しいターミナルが開きます。 + + これにより、ワークスペースフォルダ(つまり `qmk_firmware` フォルダ)でターミナルが起動し、キーボードをコンパイルすることができます。 + + +## 他の全てのオペレーティングシステム + +1. [VS Code](https://code.visualstudio.com/) に進み、インストーラをダウンロードします +2. インストーラを実行します +3. 以上です + +いいえ、本当に以上です。必要なパスはパッケージのインストール時に既に含まれています。現在のワークスペースのファイルを検出し、IntelliSense 用に解析する方がより良いです。 + +## プラグイン + +インストールした方が良い拡張が幾つかあります。 + +* [Git Extension Pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack) - +これは QMK ファームウェアで Git を簡単に使用できる Git 関連ツールを多数インスールします。 +* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - _[オプション]_ - QMK コーディング規約にコードを準拠させるのに役立ちます。 +* [Bracket Pair Colorizer 2](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2) - _[オプション]_ - これはネストされたコードを参照しやすくするために、コード内の括弧を色分けします。 +* [GitHub Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview) - _[オプション]_ - VS Code の markdown プレビューを GithHub のようにします。 +* [VS Live Share Extension Pack](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) - _[オプション]_ - この拡張により、他の誰かがあなたのワークスペースにアクセスし(あるいは、あなたが他の誰かのワークスペースにアクセスし)、手伝うことができます。あなたが問題を抱えており、他の誰かの助けが必要な場合に便利です。 +* [VIM Keymap](https://marketplace.visualstudio.com/items?itemName=GiuseppeCesarano.vim-keymap) - _[オプション]_ - VIM スタイルのキーバインドを好む人向け。これには他のオプションもあります。 +* [Travis CI Status](https://marketplace.visualstudio.com/items?itemName=felixrieseberg.vsc-travis-ci-status) - _[オプション]_ - セットアップした場合、現在の Travis CI の状態を表示します。 + +いずれかの拡張機能をインストールしたら、再起動します。 + +# QMK 用の VS Code の設定 +1. ファイル > フォルダーを開く をクリックします +2. GitHub からクローンした QMK ファームウェアフォルダを開きます。 +3. ファイル > 名前を付けてワークスペースを保存... をクリックします + +これで、VS Code で QMK ファームウェアをコーディングする準備ができました。 diff --git a/ja/pr_checklist.md b/ja/pr_checklist.md new file mode 100644 index 00000000000..9026ac48669 --- /dev/null +++ b/ja/pr_checklist.md @@ -0,0 +1,134 @@ +# PR チェックリスト + + + +これは、提出された PR を QMK の協力者がレビューする際に何をチェックするのかの非網羅的なチェックリストです。 + +これらの推奨事項に矛盾がある場合は、このドキュメントに対して [issue を開く](https://github.com/qmk/qmk_firmware/issues/new)か、[Discord](https://discord.gg/Uq7gcHh) の QMK コラボレータに連絡することをお勧めします。 + +## 一般的な PR + +- PRは、ソースリポジトリ上の `master` ではないブランチを使って提出する必要があります + - これは、あなたの PR にとって別のブランチをターゲットにするという意味ではなく、むしろ自分の master ブランチで作業をしていないという意味です + - もし PR の提出者が自分の `master` ブランチを使っている場合は、マージ後に ["git の使い方"](https://docs.qmk.fm/#/ja/newbs_git_using_your_master_branch) ページへのリンクが表示されます - (このドキュメントの最後にはメッセージの内容が含まれます) +- 新しく追加されたディレクトリとファイル名は小文字でなければなりません + - 上流のソースが元々大文字を使っていた場合 (ChibiOS や他のリポジトリからインポートしたファイルなど)、このルールは緩和されるかもしれません + - 十分な正当性がある場合 (既存のコアファイルとの整合性など) は、このルールを緩和することができます。 + - ボードデザイナーがキーボードの名前を大文字にした場合は、十分な正当性とはみとめられません +- すべての `*.c` および `*.h` ソースファイルの有効なライセンスヘッダ + - 一貫性のために GPL2/GPL3 が推奨されています + - 他のライセンスも許可されていますが、GPL と互換性があり、再配布が許可されていなければなりません。異なるライセンスを使うと、PR がマージされるのをほぼ確実に遅らせることになります +- QMK コードベースの「ベストプラクティス」に従う + - これは網羅的なリストではありませんし、時間が経つにつれて修正される可能性が高いです + - ヘッダファイルでは、`#ifndef` インクルードガードの代わりに `#pragma once` を使います + - 「旧式の」 GPIO/I2C/SPI 関数を使用しない - 正当な理由がない限り、QMK の抽象化を使用しなければなりません (怠惰は正当な理由にはなりません) + - タイミングの抽象化にも従う必要があります: + - `_delay_ms()` のかわりに `wait_ms()` を。(`#include ` も消します) + - `timer_read()` と `timer_read32()` など。 -- タイミング API は [timer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/timer.h) を参照してください + - 新しい抽象化が有用だと思う場合は、次のことをお勧めします: + - 機能が完成するまで自分のキーボードでプロトタイプを作成する + - Discord の QMK コラボレータと話し合う + - 個別のコア変更としてそれをリファクタリングする + - あなたのキーボードからそのコピーを削除する +- PR を開く前にリベースしてマージの競合をすべて修正します (ヘルプやアドバイスが必要な場合は、Discord で QMK コラボレータに連絡してください)。 + +## キーマップの PR + +- 特定のボードファイルをインクルードするよりも `#include QMK_KEYBOARD_H` を推奨します +- レイヤーは `#define` よりも `enum` が好まれます +- カスタムキーコードは `#define` ではなく `enum` が必要です。最初のエントリには `= SAFE_RANGE` が必要です +- LAYOUT マクロ呼び出しのパラメータの途中の改行ではバックスラッシュ(`\`)は不要です +- スペーシング(コンマまたはキーコードの最初の文字の配置など)に注意を払うと、見栄えの良いキーマップになります + +## キーボードの PR + +終了した PR(インスピレーションを得るために、以前のレビューコメントセットは、自分のレビューのピンポンをなくすのに役立ちます): +https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard + +- `info.json` + - 有効な URL + - 有効なメンテナ + - Configurator で正しく表示されること(Ctrl + Shift + I を押してローカルファイルをプレビューし、高速入力をオンにして順序を確認する) +- `readme.md` + - 標準テンプレートがあること + - 書き込みコマンドが `:flash` で終わっていること + - 有効なハードウェアの入手方法へのリンク (手配線の場合を除く) -- プライベートな共同購入は問題ありませんが、一回限りのプロトタイプは疑問視されます。オープンソースの場合は、ファイルへのリンクを提供してください + - ボードをブートローダーモードにリセットする方法を明確に説明してください + - キーボードの写真、できれば PCB の写真も添付してください +- `rules.mk` + - `MIDI_ENABLE`、`FAUXCLICKY_ENABLE`、`HD44780_ENABLE` は削除されました + - `# Enable Bluetooth with the Adafruit EZ-Key HID` は `# Enable Bluetooth` に変更されました + - 機能の有効化に関する `(-/+サイズ)` コメントはなくなりました + - ブートローダが指定されている場合は、代替ブートローダのリストを削除します + - [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/quantum/mcu_selection.mk)の同等の MCU と比較した場合、同じ値の場合、デフォルトの MCU パラメータの再定義がないこと +- キーボードの `config.h` + - `PRODUCT` 値に `MANUFACTURER` を繰り返さないでください + - `#define DESCRIPTION` は要りません + - マジックキーオプション、 MIDI オプション、HD44780 コンフィギュレーションは要りません + - ユーザー設定の設定可能な `#define` はキーマップ `config.h` に移動する必要があります + - "`DEBOUNCING_DELAY`" の代りに "`DEBOUNCE`" を使います + - キーボードが QMK で起動するために最低限必要なコードが存在する必要があります + - マトリックスと重要なデバイスの初期化コード + - (カスタムキーコードや特別なアニメーションなど)商用キーボードの既存の機能をミラーリングする場合は、`default` ではないキーマップを使って処理する必要があります +- `keyboard.c` + - 空の `xxxx_xxxx_kb()` または他の weak-define のデフォルト実装関数が削除されていること + - コメントアウトされた関数も削除されていること + - `matrix_init_board()` などが `keyboard_pre_init_kb()` に移行されました。[keyboard_pre_init*](https://docs.qmk.fm/#/ja/custom_quantum_functions?id=keyboard_pre_init_-function-documentation) を参照してください + - カスタムマトリックスを使用する場合は、`CUSTOM_MATRIX = lite` を選択し、標準のデバウンスを許可します。[マトリックスコードの部分置き換え](https://docs.qmk.fm/#/ja/custom_matrix?id=lite) を参照してください +- `keyboard.h` + - 先頭に `#include "quantum.h"` を置きます + - `LAYOUT` マクロは、該当する場合は標準の定義を使用してください + - 該当する場合はコミュニティレイアウトマクロ名を使用します (`LAYOUT`/`LAYOUT_all`よりも優先されます) +- キーマップの `config.h` + - キーボードから `rules.mk` や `config.h` が重複していないこと +- `keymaps/default/keymap.c` + - `QMKBEST`/`QMKURL` が削除されていること + - `MO(_LOWER)`および `MO(_RAISE)`キーコードまたは同等のものを使用していて、キーマップに両方のキーを押したときに adjust レイヤーがある場合 - キーマップに直接 adjust レイヤーに入るキーコードがない場合(`MO(_ADJUST)`のように)次のように記述します... + ``` + layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); + } + ``` + ...キーマップの `process_record_user()` 内で `layer_on()`、 `update_tri_layer()` を手動で処理する代わりに。 +- default (および via) のキーマップは「素朴」でなければなりません。 + - 他のユーザーが独自のユーザー固有のキーマップを開発するための「クリーンな状態」として使用するための最低限のもの。 + - これらのキーマップで推奨される標準レイアウト(可能な場合) +- PR の提出者は、同じ PR に機能を紹介する個人的な(または豪華な)キーマップを持たせることができますが、「デフォルト」のキーマップに埋め込むべきではありません +- PR の提出者はまた、既存の商用キーボードへ QMK を移植する場合、その商用製品の既存の機能を反映する「製造業者に一致する」キーマップを持つことができます + +さらに、ChibiOS に固有で: +- 既存の ChibiOS ボード定義を使用することを**強く**推奨します。 + - 多くの場合、同等の Nucleo ボードは、同じファミリの異なるフラッシュサイズまたはわずかに異なるモデルで使用できます。 + - 例:STM32L082KZ の場合、STM32L073RZ に類似しているため、rules.mkで `BOARD = ST_NUCLEO64_L073RZ` を使用できます。 + - QMK は ChibiOS のアップグレード時のメンテナンス負担が継続的に発生するため、可能な限りカスタムボード定義を持たないように移行しています。 +- ボードの定義が避けられない場合、`board.c` には標準の `__early_init()` (通常の ChibiOS ボードの定義と同じ) と空の `boardInit()` を実装しなければなりません。 + - Arm/ChibiOS [早期初期化](https:/docs.qmk.fm/#/ja/platformdev_chibios_earlyinit?id=board-init)を参照してください + - `__early_init()`は、`early_hardware_init_pre()` または `early_hardware_init_post()` で適切に置き換える必要があります + - `boardInit()` は `board_init()` に移行する必要があります + +## コアの PR + +- `develop` ブランチをターゲットにする必要があります。これは、その後、breaking change のタイムラインで `master` にマージされます。 +- その他の注意事項 TBD + - 投稿された変更の幅を考えると、コアはもっと主観的です + +--- + +## 注意事項 + +人々が自分の `master` ブランチを使用する場合、マージ後に以下を投稿します: + +``` +For future reference, we recommend against committing to your `master` branch as you've done here, because pull requests from modified `master` branches can make it more difficult to keep your QMK fork updated. It is highly recommended for QMK development – regardless of what is being done or where – to keep your master updated, but **NEVER** commit to it. Instead, do all your changes in a branch (branches are basically free in Git) and issue PRs from your branches when you're developing. + +There are instructions on how to keep your fork updated here: + +[**Best Practices: Your Fork's Master: Update Often, Commit Never**](https://docs.qmk.fm/#/newbs_git_using_your_master_branch) + +[Fixing Your Branch](https://docs.qmk.fm/#/newbs_git_resynchronize_a_branch) will walk you through fixing up your `master` branch moving forward. If you need any help with this just ask. + +Thanks for contributing! +``` diff --git a/ja/proton_c_conversion.md b/ja/proton_c_conversion.md new file mode 100644 index 00000000000..6e4f7dcb663 --- /dev/null +++ b/ja/proton_c_conversion.md @@ -0,0 +1,97 @@ +# キーボードを Proton C を使うように変更 + + + +Proton C は Pro Micro の差し替え可能品であるため、簡単に使用することができます。 +このページでは、キーボードを変換するための便利な自動化されたプロセスと、Pro Micro では利用できない Proton C の機能を利用したい場合の手動プロセスについて説明しています。 + +## 自動で変換 + +QMK で現在サポートされているキーボードが Pro Micro(または互換ボード)を使用しており、Proton C を使用したい場合は、以下のように make 引数に `CONVERT_TO_PROTON_C=yes` (または `CTPC=yes`) を追加することでファームウェアを生成することができます。 + + make 40percentclub/mf68:default CTPC=yes + +同じ引数をキーマップの `rules.mk` に追加しても同じことができます。 + +これは、次のように、`#ifdef` を使用してコード内で使用できる `CONVERT_TO_PROTON_C` フラグを公開します。 + +```c +#ifdef CONVERT_TO_PROTON_C + // Proton C code +#else + // Pro Micro code +#endif +``` + +`PORTB/DDRB` などが定義されていないというエラーが発生した場合は、ARM と AVR の両方で機能する [GPIO 制御](ja/internals_gpio_control.md) を使用するようにキーボードのコードを変換する必要があります。これは AVR ビルドにまったく影響を与えません。 + +Proton C には1つのオンボード LED(C13)しかなく、デフォルトでは TXLED(D5) がそれにマップされています。代わりに RXLED(B0) をそれにマッピングしたい場合は、`config.h` に次のように追加してください。 + + #define CONVERT_TO_PROTON_C_RXLED + +## 機能の変換 + +下記は ARM ボードに実装されているものに基づいたデフォルトです。 + +| 機能 | 説明 | +|--------------------------------------|------------------------------------------------------------------------------------| +| [オーディオ](ja/feature_audio.md) | 有効 | +| [RGB ライト](ja/feature_rgblight.md) | 無効 | +| [バックライト](feature_backlight.md) | ARM が自動コンフィギュレーションを提供できるようになるまで、[タスク駆動 PWM](ja/(feature_backlight.md#software-pwm-driver))が強制されます | +| USB ホスト (例えば USB-USB コンバータ) | 未サポート (USB ホストコードは AVR 固有のもので、現在 ARM ではサポートされていません。 | +| [分割キーボード](ja/feature_split_keyboard.md) | 部分的 - 有効にする機能に大きく依存します | + +## 手動で変換 + +`CTPC = yes` を指定せずに Proton C をネイティブで使用するには、`rules.mk` の `MCU`行を変更する必要があります: + +``` +MCU = STM32F303 +``` + +次の変数が存在する場合は削除します。 + +* `BOOTLOADER` +* `EXTRA_FLAGS` + +最後に、`config.h`のすべてのピン割り当てを STM32 上の同等のものに変換します。 + +| Pro Micro 左側| Proton C 左側 | | Proton C 右側 | Pro Micro 右側 | +|--------------|--------------|-|--------------|---------------| +| `D3` | `A9` | | 5v | RAW (5v) | +| `D2` | `A10` | | GND | GND | +| GND | GND | | FLASH | RESET | +| GND | GND | | 3.3v | Vcc 1 | +| `D1` | `B7` | | `A2` | `F4` | +| `D0` | `B6` | | `A1` | `F5` | +| `D4` | `B5` | | `A0` | `F6` | +| `C6` | `B4` | | `B8` | `F7` | +| `D7` | `B3` | | `B13` | `B1` | +| `E6` | `B2` | | `B14` | `B3` | +| `B4` | `B1` | | `B15` | `B2` | +| `B5` | `B0` | | `B9` | `B6` | +| `B0` (RX LED) | `C13` 2 | | `C13` 2 | `D5` (TX LED) | + +また、Proton C の拡張部分にあるいくつかの新しいピンを利用することもできます。 + +| 左側 | | 右側 | +|------|-|-------| +| `A4`3 | | `B10` | +| `A5`4 | | `B11` | +| `A6` | | `B12` | +| `A7` | | `A14`5 (SWCLK) | +| `A8` | | `A13`5 (SWDIO) | +| `A15` | | RESET6 | + +注釈: + +1. Pro Micro の Vcc は 3.3V または 5V にすることができます。 +2. Proton C のオンボード LED は、Pro Micro のように2つはありません、1つだけです。Pro Micro には、RX LED(`D5`) と TX LED(`B0`)があります。 +3. `A4` ピンは、スピーカーと共有されています。 +4. `A5` ピンは、スピーカーと共有されています。 +5. `A13` と `A14` ピンはハードウェアデバッグ (SWD) に使用されます。GPIO にも使えますが、最後に使ってください。 +6. RESET を 3.3V とショート(プルアップ)して MCU をリブートします。これは Pro Micro のようにブートローダモードにはならず、MCU をリセットするだけです。 diff --git a/ja/quantum_keycodes.md b/ja/quantum_keycodes.md new file mode 100644 index 00000000000..ffcc4944609 --- /dev/null +++ b/ja/quantum_keycodes.md @@ -0,0 +1,20 @@ +# Quantum キーコード + + + +Quantum キーコードにより、カスタムアクションを定義することなく、基本的なものが提供するものより簡単にキーマップをカスタマイズすることができます。 + +quantum 内の全てのキーコードは `0x0000` と `0xFFFF` の間の数値です。`keymap.c` の中では、関数やその他の特別な場合があるように見えますが、最終的には C プリプロセッサによってそれらは単一の4バイト整数に変換されます。QMK は標準的なキーコードのために `0x0000` から `0x00FF` を予約しています。これらは、`KC_A`、`KC_1` および `KC_LCTL` のようなキーコードで、USB HID 仕様で定義された基本的なキーです。 + +このページでは、高度な quantum 機能を実装するために使われる `0x00FF` と `0xFFFF` の間のキーコードを説明します。独自のカスタムキーコードを定義する場合は、それらもこの範囲に配置されます。 + +## QMK キーコード :id=qmk-keycodes + +| キー | エイリアス | 説明 | +|----------------|------------|--------------------------------------------------------| +| `RESET` | | 書き込みのために、キーボードを bootloader モードにする | +| `DEBUG` | | デバッグモードの切り替え | +| `EEPROM_RESET` | `EEP_RST` | キーボードの EEPROM (永続化メモリ) を再初期化する | diff --git a/ja/ref_functions.md b/ja/ref_functions.md new file mode 100644 index 00000000000..029797ff013 --- /dev/null +++ b/ja/ref_functions.md @@ -0,0 +1,124 @@ +# キーボードをより良くするための便利なコア関数のリスト + + + +QMK には、信じられないほど便利な、またはあなたが望んでいた機能を少し追加する、隠された関数がたくさんあります。特定の機能に固有の関数はそれぞれの機能のページにあるため、ここには含まれていません。 + +## (OLKB) トライレイヤー :id=olkb-tri-layers + +目的に応じて、実際に使うことができる別個の関数があります。 + +### `update_tri_layer(x, y, z)` + +最初は `update_tri_layer(x, y, z)` 関数です。この関数はレイヤー `x` と `y` の両方がオンになっているかどうかを調べます。両方ともオンの場合は、レイヤー `z` がオンになります。それ以外の場合、`x` と `y` の両方がオンではない(一方のみがオン、またはどちらもオンでない)場合は、レイヤー `z` をオフにします。 + +この関数は、この機能を持つ特定のキーを作成したいが、他のレイヤーのキーコードではそうしたくない場合に便利です。 + +#### 例 + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + case RAISE: + if (record->event.pressed) { + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + } + return true; +} +``` + +### `update_tri_layer_state(state, x, y, z)` +もう1つの関数は `update_tri_layer_state(state, x, y, z)` です。この関数は [`layer_state_set_*` 関数](ja/custom_quantum_functions.md#layer-change-code)から呼び出されることを意図しています。これは、キーコードを使ってレイヤーを変更するたびに、これがチェックされることを意味します。したがって、`LT(layer, kc)` を使ってレイヤーを変更すると、同じレイヤーチェックが引き起こされます。 + +このメソッドの注意点は2つあります: +1. `x` および `y` レイヤーをオンにしないと、`z` レイヤーにアクセスできません。これは、レイヤー `z` のみをアクティブにしようとすると、このコードが実行され、使用前にレイヤー `z` がオフになるからです。 +2. レイヤーは最上位の番号から処理されるので、`z` は `x` や `y` よりも上位のレイヤーでなければなりません。そうでなければアクセスできない場合があります。 + +#### 例 + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} +``` + +あるいは、すぐに値を「返す」必要はありません。複数のトライレイヤーを追加、あるいは追加の効果を追加する場合に便利です。 + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); + state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL); + return state; +} +``` + +## 永続的なデフォルトレイヤーの設定 + +デフォルトレイヤーを設定して、キーボードを取り外しても保持されるようにしたいですか?そうであれば、これがそのための関数です。 + +これを使うには、`set_single_persistent_default_layer(layer)` を使います。レイヤーに名前が定義されている場合は、代わりにそれを使うことができます (_QWERTY、_DVORAK、_COLEMAK など)。 + +これは、デフォルトレイヤーを設定し、永続設定が更新され、もし [オーディオ](ja/feature_audio.md) がキーボードで有効でデフォルトレイヤーの音が設定されている場合は、曲を再生します。 + +デフォルトレイヤーの音を設定するには、以下のように `config.h` ファイルに定義する必要があります。 + +```c +#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +``` + + +?> [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) に使用できる多くの定義済みの曲があります。 + +## キーボードのリセット + +使用できる `RESET` quantum キーコードがあります。ただし、キーを個別に押すのではなくマクロの一部としてリセットしたい場合は、そうすることができます。 + +そのためには、`reset_keyboard()` を関数またはマクロに追加すると、ブートローダがリセットされます。 + +## EEPROM (永続ストレージ)の消去 + +オーディオ、RGB アンダーグロー、バックライト、キーの動作に問題がある場合は、EEPROM (永続的な設定のストレージ)をリセットすることができます。ブートマジックはこれを行う方法の1つですが、有効になっていない場合はカスタムマクロを使って行うことができます。 + +EEPROM を消去するには、関数またはマクロから `eeconfig_init()` を実行し、ほとんどの設定をデフォルトにリセットします。 + +## タップランダムキー + +ランダムな文字をホストコンピュータに送信する場合は、`tap_random_base64()` 関数を使うことができます。これは[疑似乱数的に](https://en.wikipedia.org/wiki/Pseudorandom_number_generator)0から63の数字を選択し、その選択に基づいてキー押下を送信します。(0–25 は `A`–`Z`、26–51 は `a`–`z`、52–61 は `0`–`9`、62 は `+`、63 は `/`)。 + +?> 言うまでもないですが、これはランダムに Base64 キーあるいはパスワードを生成する暗号的に安全な方法では _ありません_。 + +## ソフトウェアタイマー + +タイマーを開始し、時間固有のイベントの値を読み取ることができます。以下は例です: + +```c +static uint16_t key_timer; +key_timer = timer_read(); + +if (timer_elapsed(key_timer) < 100) { + // 経過時間が 100ms 未満の場合に何かを行う +} else { + // 経過時間が 100ms 以上の場合に何かを行う +} +``` diff --git a/ja/reference_configurator_support.md b/ja/reference_configurator_support.md new file mode 100644 index 00000000000..0151731e99a --- /dev/null +++ b/ja/reference_configurator_support.md @@ -0,0 +1,202 @@ +# QMK Configurator でのキーボードのサポート + + + +このページは [QMK Configurator](https://config.qmk.fm/) でキーボードを適切にサポートする方法について説明します。 + + +## Configurator がキーボードを理解する方法 + +Configurator がキーボードをどのように理解するかを理解するには、最初にレイアウトマクロを理解する必要があります。この演習では、17キーのテンキー PCB を想定します。これを `numpad` と呼びます。 + +``` +|---------------| +|NLk| / | * | - | +|---+---+---+---| +|7 |8 |9 | + | +|---+---+---| | +|4 |5 |6 | | +|---+---+---+---| +|1 |2 |3 |Ent| +|-------+---| | +|0 | . | | +|---------------| +``` + +?> レイアウトマクロの詳細については、[QMK の理解: マトリックススキャン](ja/understanding_qmk.md?id=matrix-scanning) と [QMK の理解: マトリックスから物理レイアウトへのマップ](ja/understanding_qmk.md?id=matrix-to-physical-layout-map) を見てください。 + +Configurator の API はキーボードの `.h` ファイルを `qmk_firmware/keyboards//.h` から読み取ります。numpad の場合、このファイルは `qmk_firmware/keyboards/numpad/numpad.h` です: + +```c +#pragma once + +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ + ) { \ + { k00, k01, k02, k03 }, \ + { k10, k11, k12, k13 }, \ + { k20, k21, k22, KC_NO }, \ + { k30, k31, k32, k33 }, \ + { k40, KC_NO, k42, KC_NO } \ +} +``` + +QMK は `KC_NO` を使って、スイッチマトリックス内のスイッチがない場所を指定します。デバッグが必要な場合に、このセクションを読みやすくするために、`XXX`、`___`、`____` を略記として使うこともあります。通常は `.h` ファイルの先頭近くで定義されます: + +```c +#pragma once + +#define XXX KC_NO + +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ + ) { \ + { k00, k01, k02, k03 }, \ + { k10, k11, k12, k13 }, \ + { k20, k21, k22, XXX }, \ + { k30, k31, k32, k33 }, \ + { k40, XXX, k42, XXX } \ +} +``` + +!> この使用方法はキーマップマクロと異なります。キーマップマクロはほとんど常に`KC_NO`については`XXXXXXX` (7つの大文字の X) を、`KC_TRNS` については `_______` (7つのアンダースコア)を使います。 + +!> ユーザの混乱を防ぐために、`KC_NO` を使うことをお勧めします。 + +レイアウトマクロは、キーボードに17個のキーがあり、4列それぞれが5行に配置されていることを Configurator に伝えます。スイッチの位置は、0から始まる `k` という名前が付けられています。キーマップからキーコードを受け取る上部セクションと、マトリックス内の各キーの位置を指定する下部セクションとが一致する限り、名前自体は実際には問題ではありません。 + +物理的なキーボードに似た形でキーボードを表示するには、それぞれのキーの物理的な位置とサイズをスイッチマトリックスに結びつけることを Configurator に伝える JSON ファイルを作成する必要があります。 + +## JSON ファイルのビルド + +JSON ファイルをビルドする最も簡単な方法は、[Keyboard Layout Editor](http://www.keyboard-layout-editor.com/) ("KLE") でレイアウトを作成することです。この Raw Data を QMK tool に入れて、Configurator が読み出して使用する JSON ファイルに変換します。KLE は numpad レイアウトをデフォルトで開くため、Getting Started の説明を削除し、残りを使います。 + +レイアウトが望み通りのものになったら、KLE の Raw Data タブに移動し、内容をコピーします: + +``` +["Num Lock","/","*","-"], +["7\nHome","8\n↑","9\nPgUp",{h:2},"+"], +["4\n←","5","6\n→"], +["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"], +[{w:2},"0\nIns",".\nDel"] +``` + +このデータを JSON に変換するには、[QMK KLE-JSON Converter](https://qmk.fm/converter/) に移動し、Raw Data を Input フィールド に貼り付け、Convert ボタンをクリックします。しばらくすると、JSON データが Output フィールドに表示されます。内容を新しいテキストドキュメントにコピーし、ドキュメントに `info.json` という名前を付け、`numpad.h` を含む同じフォルダに保存します。 + +`keyboard_name` オブジェクトを使ってキーボードの名前を設定します。説明のために、各キーのオブジェクトを各行に配置します。これはファイルを人間が読みやすいものにするためのもので、Configurator の機能には影響しません。 + +```json +{ + "keyboard_name": "Numpad", + "url": "", + "maintainer": "qmk", + "tags": { + "form_factor": "numpad" + }, + "width": 4, + "height": 5, + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"Num Lock", "x":0, "y":0}, + {"label":"/", "x":1, "y":0}, + {"label":"*", "x":2, "y":0}, + {"label":"-", "x":3, "y":0}, + {"label":"7", "x":0, "y":1}, + {"label":"8", "x":1, "y":1}, + {"label":"9", "x":2, "y":1}, + {"label":"+", "x":3, "y":1, "h":2}, + {"label":"4", "x":0, "y":2}, + {"label":"5", "x":1, "y":2}, + {"label":"6", "x":2, "y":2}, + {"label":"1", "x":0, "y":3}, + {"label":"2", "x":1, "y":3}, + {"label":"3", "x":2, "y":3}, + {"label":"Enter", "x":3, "y":3, "h":2}, + {"label":"0", "x":0, "y":4, "w":2}, + {"label":".", "x":2, "y":4} + ] + } + } +} +``` + +`layouts` オブジェクトにはキーボードの物理レイアウトを表すデータが含まれます。このオブジェクトには `LAYOUT` という名前のオブジェクトがあり、このオブジェクト名は `numpad.h` のレイアウトマクロの名前と一致する必要があります。`LAYOUT` オブジェクト自体には `layout` という名前のオブジェクトがあります。このオブジェクトにはキーボードの物理キーごとに 1つの JSON オブジェクトが以下の形式で含まれています: + +``` + キーの名前。Configurator では表示されません。 + | + | キーボードの左端からのキー単位での + | | キーの X 軸の位置。 + | | + | | キーボードの上端(奥側)からのキー単位での + | | | キーの Y 軸位置。 + ↓ ↓ ↓ +{"label":"Num Lock", "x":0, "y":0}, +``` + +一部のオブジェクトには、それぞれキーの幅と高さを表す `"w"` 属性キーと `"h"` 属性キーがあります。 + +?> `info.json` ファイルの詳細については、[`info.json` 形式](ja/reference_info_json.md) を参照してください。 + + +## Configurator がキーをプログラムする方法 + +Configurator の API は、指定されたレイアウトマクロと JSON ファイルを使って、特定のキーに関連付けられた各ビジュアルオブジェクトを順番に持つキーボードのビジュアル表現を作成します: + +| レイアウトマクロのキー | 使用される JSON オブジェクト | +:---: | :---- +| k00 | {"label":"Num Lock", "x":0, "y":0} | +| k01 | {"label":"/", "x":1, "y":0} | +| k02 | {"label":"*", "x":2, "y":0} | +| k03 | {"label":"-", "x":3, "y":0} | +| k10 | {"label":"7", "x":0, "y":1} | +| k11 | {"label":"8", "x":1, "y":1} | +| k12 | {"label":"9", "x":2, "y":1} | +| k13 | {"label":"+", "x":3, "y":1, "h":2} | +| k20 | {"label":"4", "x":0, "y":2} | +| k21 | {"label":"5", "x":1, "y":2} | +| k22 | {"label":"6", "x":2, "y":2} | +| k30 | {"label":"1", "x":0, "y":3} | +| k31 | {"label":"2", "x":1, "y":3} | +| k32 | {"label":"3", "x":2, "y":3} | +| k33 | {"label":"Enter", "x":3, "y":3, "h":2} | +| k40 | {"label":"0", "x":0, "y":4, "w":2} | +| k42 | {"label":".", "x":2, "y":4} | + +ユーザが Configurator で左上のキーを選択し、Num Lock を割り当てると、Configurator は最初のキーとして `KC_NLCK` を持つキーマップを作成し、同様にキーマップが作成されます。`label` キーは使われません; それらは `info.json` ファイルをデバッグする時に特定のキーを識別するためのユーザの参照のためだけのものです。 + + +## 問題と危険 + +現在のところ、Configurator はキーの回転または ISO Enter などの長方形ではないキーをサポートしません。さらに、"行"から垂直方向にずれているキー、— 顕著な例として [TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/) のような1800レイアウト上の矢印キー — は、 `info.json` ファイルの提供者によって調整されていない場合は、KLE-to-JSON コンバータを混乱させます。 + +### 回避策 + +#### 長方形ではないキー + +ISO Enter キーについては、QMK custom は幅 1.25u、高さ 2u の長方形のキーとして表示し、右端が英数字キーブロックの右端に揃うように配置されます。 + +![](https://i.imgur.com/JKngtTw.png) +*QMK Configurator によって描画される標準 ISO レイアウトの60%キーボード。* + +#### 垂直方向にずれたキー + +垂直方向にずれたキーについては、ずれていないかのように KLE で配置し、変換された JSON ファイルで必要に応じて Y 値を編集します。 + +![](https://i.imgur.com/fmDvDzR.png) +*矢印キーに適用される垂直方向のずれのない、Keyboard Layout Editor で描画された1800レイアウトのキーボード。* + +![](https://i.imgur.com/8beYMBR.png) +*キーボードの JSON ファイルで矢印キーを垂直方向にずらすために必要な変更を示す、Unix の diff ファイル。* diff --git a/ja/reference_glossary.md b/ja/reference_glossary.md new file mode 100644 index 00000000000..19791206f17 --- /dev/null +++ b/ja/reference_glossary.md @@ -0,0 +1,173 @@ +# QMK 用語集 + + + +## ARM +Atmel、Cypress、Kinetis、NXP、ST、TI など多くの企業が生産する 32 ビット MCU のライン。 + +## AVR +[Atmel](http://www.microchip.com/) が生産する 8 ビット MCU のライン。AVR は TMK がサポートしていた元のプラットフォームでした。 + +## AZERTY +標準的な Français (フランス) キーボードレイアウト。キーボードの最初の6つのキーから命名されました。 + +## バックライト +キーボードのライトの総称。バックライトが一般的ですが、それだけではなく、キーキャップあるいはスイッチを通して光る LED の配列。 + +## Bluetooth +短距離のピアツーピア無線プロトコル。キーボード用のもっとも一般的なワイヤレスプロトコル。 + +## ブートローダ +MCU の保護領域に書き込まれる特別なプログラムで、MCU が独自のファームウェアを通常は USB 経由でアップグレードできるようにします。 + +## ブートマジック +よくあるキーの交換あるいは無効化など、様々なキーボードの挙動の変更をその場で実行できる機能。 + +## C +システムコードに適した低レベルプログラミング言語。QMK のほとんどのコードは C で書かれています。 + +## Colemak +人気が出始めている代替キーボードレイアウト。 + +## コンパイル +人間が読めるコードを MCU が実行できるマシンコードに変換するプロセス。 + +## Dvorak +1930年代に Dr. August Dvorak によって開発された代替キーボードレイアウト。Dvorak Simplified Keyboard の短縮形。 + +## 動的マクロ +キーボードに記録されたマクロで、キーボードのプラグを抜くか、コンピュータを再起動すると失われます。 + +* [動的マクロドキュメント](ja/feature_dynamic_macros.md) + +## Eclipse +多くの C 開発者に人気のある IDE。 + +* [Eclipse セットアップ手順](ja/other_eclipse.md) + +## ファームウェア +MCU を制御するソフトウェア + +## git +コマンドラインで使用されるバージョン管理ソフトウェア + +## GitHub +QMK プロジェクトのほとんどをホストする Web サイト。git、課題管理、および QMK の実行に役立つその他の機能を統合して提供します。 + +## ISP +インシステムプログラミング。外部ハードウェアと JTAG ピンを使って AVR チップをプログラミングする方法。 + +## hid_listen +キーボードからデバッグメッセージを受信するためのインタフェース。[QMK Flasher](https://github.com/qmk/qmk_flasher) あるいは [PJRC の hid_listen](https://www.pjrc.com/teensy/hid_listen.html) を使ってこれらのメッセージを見ることができます。 + +## キーコード +特定のキーを表す2バイトの数値。`0x00`-`0xFF` は[基本キーコード](ja/keycodes_basic.md)に使われ、`0x100`-`0xFFFF` は [Quantum キーコード](ja/quantum_keycodes.md) に使われます。 + +## キーダウン +キーが押された時に発生し、キーが放される前に完了するイベント。 + +## キーアップ +キーが放された時に発生するイベント。 + +## キーマップ +物理的なキーボードレイアウトにマップされたキーコードの配列。キーの押下およびリリース時に処理されます。 + +## レイヤー +1つのキーが複数の目的を果たすために使われる抽象化。最上位のアクティブなレイヤーが優先されます。 + +## リーダーキー +リーダーキーに続けて1, 2 あるいは3つのキーをタップすることで、キーの押下あるいは他の quantum 機能をアクティブにする機能。 + +* [リーダーキードキュメント](ja/feature_leader_key.md) + +## LED +発光ダイオード。キーボードの表示に使われる最も一般的なデバイス。 + +## Make +全てのソースファイルをコンパイルするために使われるソフトウェアパッケージ。キーボードファームウェアをコンパイルするために、様々なオプションを指定して `make` を実行します。 + +## マトリックス +MCU がより少ないピン数でキー押下を検出できるようにする列と行の配線パターン。マトリックスには多くの場合、NKRO を可能にするためのダイオードが組み込まれています。 + +## マクロ +単一のキーのみを押した後で、複数のキー押下イベント (HID レポート) を送信できる機能。 + +* [マクロドキュメント](ja/feature_macros.md) + +## MCU +マイクロコントロールユニット。キーボードを動かすプロセッサ。 + +## モディファイア +別のキーを入力する間押したままにして、そのキーのアクションを変更するキー。例として、Ctrl、Alt および Shift があります。 +(訳注:モディファイヤ、モディファイヤキー、修飾キーなど、訳語が統一されていませんが同じものです) + +## マウスキー +キーボードからマウスカーソルを制御し、クリックできる機能。 + +* [マウスキードキュメント](ja/feature_mouse_keys.md) + +## N キーロールオーバー (NKRO) +一度に任意の数のキーの押下を送信できるキーボードに当てはまる用語。 + +## ワンショットモディファイア +別のキーが放されるまで押されているかのように機能するモディファイア。キーを押している間に mod を押し続けるのではなく、mod を押してからキーを押すことができます。スティッキーキーまたはデッドキーとも呼びます。 + +## ProMicro +低コストの AVR 開発ボード。このデバイスのクローンは ebay で非常に安価(5ドル未満)に見つかることがありますが、多くの場合 pro micro の書き込みに苦労します。 + +## プルリクエスト +QMK にコードを送信するリクエスト。全てのユーザが個人のキーマップのプルリクエストを送信することを推奨します。 + +## QWERTY +標準の英語キーボードレイアウト。多くの場合、他の言語の標準レイアウトへのショートカット。キーボードの最初の6文字から命名されました。 + +## QWERTZ +標準的な Deutsche (ドイツ語) キーボードレイアウト。キーボードの最初の6文字から命名されました。 + +## ロールオーバー +キーが既に押されている間にキーを押すことを指す用語。似たものに 2KRO、6KRO、NKRO が含まれます。 + +## スキャンコード +単一のキーを表す USB 経由の HID レポートの一部として送信される1バイトの数値。これらの値は、[USB-IF](http://www.usb.org/) が発行する [HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) に記載されています。 + +## スペースカデットシフト +左または右 shift を1回以上タップすることで、様々なタイプの括弧を入力できる特別な shift キーのセット。 + +* [スペースカデットシフトドキュメント](ja/feature_space_cadet_shift.md) + +## タップ +キーを押して放す。状況によってはキーダウンイベントとキーアップイベントを区別する必要がありますが、タップは常に両方を一度に指します。 + +## タップダンス +押す回数に基づいて、同じキーに複数のキーコードを割り当てることができる機能。 + +* [タップダンスドキュメント](ja/feature_tap_dance.md) + +## Teensy +手配線での組み立てによく用いられる低コストの AVR 開発ボード。halfkay ブートローダによって書き込みが非常に簡単になるために、数ドル高いにもかかわらず teensy がしばしば選択されます。 + +## アンダーライト +キーボードの下側を照らす LED の総称。これらの LED は通常 PCB の底面からキーボードが置かれている表面に向けて照らします。 + +## ユニコード +大規模なコンピュータの世界では、ユニコードは任意の言語で文字を表現するためのエンコード方式のセットです。QMK に関しては、様々な OS スキームを使ってスキャンコードの代わりにユニコードコードポイントを送信することを意味します。 + +* [ユニコードドキュメント](ja/feature_unicode.md) + +## 単体テスト +QMK に対して自動テストを実行するためのフレームワーク。単体テストは、変更が何も壊さないことを確信するのに役立ちます。 + +* [単体テストドキュメント](ja/unit_testing.md) + +## USB +ユニバーサルシリアルバス。キーボード用の最も一般的な有線インタフェース。 + +## USB ホスト (あるいは単にホスト) +USB ホストは、あなたのコンピュータ、またはキーボードが差し込まれているデバイスのことです。 + +# 探している用語が見つかりませんでしたか? + +質問についての [issue を開いて](https://github.com/qmk/qmk_firmware/issues) 、質問した用語についてここに追加することができます。さらに良いのは、定義についてのプルリクエストを開くことです。:) diff --git a/ja/reference_info_json.md b/ja/reference_info_json.md new file mode 100644 index 00000000000..f5889a1026d --- /dev/null +++ b/ja/reference_info_json.md @@ -0,0 +1,78 @@ +# `info.json` + + + +このファイルは [QMK API](https://github.com/qmk/qmk_api) によって使われます。このファイルは [QMK Configurator](https://config.qmk.fm/) がキーボードの画像を表示するために必要な情報を含んでいます。ここにメタデータを設定することもできます。 + +このメタデータを指定するために、`qmk_firmware/keyboards/` の下の全てのレベルで `info.json` を作成することができます。これらのファイルは結合され、より具体的なファイルがそうではないファイルのキーを上書きします。つまり、メタデータ情報を複製する必要はありません。例えば、`qmk_firmware/keyboards/clueboard/info.json` は `manufacturer` および `maintainer` を指定し、`qmk_firmware/keyboards/clueboard/66/info.json` は Clueboard 66% についてのより具体的な情報を指定します。 + +## `info.json` の形式 + +`info.json` ファイルは設定可能な以下のキーを持つ JSON 形式の辞書です。全てを設定する必要はなく、キーボードに適用するキーだけを設定します。 + +* `keyboard_name` + * キーボードを説明する自由形式のテキスト文字列。 + * 例: `Clueboard 66%` +* `url` + * キーボードの製品ページ、[QMK.fm/keyboards](https://qmk.fm/keyboards) のページ、あるいはキーボードに関する情報を説明する他のページの URL。 +* `maintainer` + * メンテナの GitHub のユーザ名、あるいはコミュニティが管理するキーボードの場合は `qmk` +* `width` + * キー単位でのキーボードの幅 +* `height` + * キー単位でのキーボードの高さ +* `layouts` + * 物理的なレイアウト表現。詳細は以下のセクションを見てください。 + +### レイアウトの形式 + +`info.json` ファイル内の辞書の `layouts` 部分は、幾つかの入れ子になった辞書を含みます。外側のレイヤーは QMK レイアウトマクロで構成されます。例えば、`LAYOUT_ansi` あるいは `LAYOUT_iso`。各レイアウトマクロ内には、`width`、 `height`、`key_count` のキーがあります。これらは自明でなければなりません。 + +* `width` + * オプション: キー単位でのレイアウトの幅 +* `height` + * オプション: キー単位でのレイアウトの高さ +* `key_count` + * オプション: このレイアウトのキーの数 +* `layout` + * 物理レイアウトを説明するキー辞書のリスト。詳細は次のセクションを見てください。 + +### キー辞書形式 + +レイアウトの各キー辞書は、キーの物理プロパティを記述します。 の Raw Code に精通している場合、多くの概念が同じであることが分かります。可能な限り同じキー名とレイアウトの選択を再利用しますが、keyboard-layout-editor とは異なって各キーはステートレスで、前のキーからプロパティを継承しません。 + +全てのキーの位置と回転は、キーボードの左上と、各キーの左上を基準にして指定されます。 + +* `x` + * **必須**: 水平軸でのキーの絶対位置(キー単位)。 +* `y` + * **必須**: 垂直軸でのキーの絶対位置(キー単位)。 +* `w` + * キー単位でのキーの幅。`ks` が指定された場合は無視されます。デフォルト: `1` +* `h` + * キー単位でのキーの高さ。`ks` が指定された場合は無視されます。デフォルト: `1` +* `r` + * キーを回転させる時計回りの角度。 +* `rx` + * キーを回転させる点の水平軸における絶対位置。デフォルト: `x` +* `ry` + * キーを回転させる点の垂直軸における絶対位置。デフォルト: `y` +* `ks` + * キー形状: キー単位で頂点を列挙することでポリゴンを定義します。 + * **重要**: これらはキーの左上からの相対位置で、絶対位置ではありません。 + * ISO Enter の例: `[ [0,0], [1.5,0], [1.5,2], [0.25,2], [0.25,1], [0,1], [0,0] ]` +* `label` + * マトリックス内のこの位置につける名前。 + * これは通常 PCB 上でこの位置にシルクスクリーン印刷されるものと同じ名前でなければなりません。 + +## メタデータはどのように公開されますか? + +このメタデータは主に2つの方法で使われます: + +* Web ベースの configurator が動的に UI を生成できるようにする。 +* 新しい `make keyboard:keymap:qmk` ターゲットをサポートする。これは、このメタデータをファームウェアにバンドルして QMK Toolbox をよりスマートにします。 + +Configurator の作成者は、JSON API の使用に関する詳細について、[QMK Compiler](https://docs.api.qmk.fm/using-the-api) ドキュメントを参照することができます。 diff --git a/ja/reference_keymap_extras.md b/ja/reference_keymap_extras.md new file mode 100644 index 00000000000..e8104e5f3e6 --- /dev/null +++ b/ja/reference_keymap_extras.md @@ -0,0 +1,88 @@ +# 言語固有のキーコード + + + +キーボードは多くの言語をサポートすることができます。ただし、それらはキーを押したことで生成される実際の文字を送信しません - 代わりに数字のコードを送信します。USB HID の仕様ではそれらは "usages" と呼ばれますが、キーボードの文脈では「スキャンコード」あるいは「キーコード」と呼ばれることが多いです。 +HID Keyboard/Keypad usage ページでは 256 未満の usage が定義されており、それらの一部は現在のオペレーティングシステムでは機能しません。では、この言語のサポートはどのようにして実現されるのでしょうか? + +簡単に言うと、オペレーティングシステムはユーザが設定したキーボードレイアウトに基づいて受け取った usage を適切な文字にマップします。例えば、スウェーデン人がキーボードの `å` という文字が刻印されたキーを押すと、キーボードは *実際には* `[` のキーコードを送信します。 + +明らかにこれは混乱する可能性があるため、QMK は多くのキーボードレイアウトのために言語固有のキーコードのエイリアスを提供します。これらはそれだけでは何もしません - さらに OS の設定で対応するキーボードレイアウトを設定する必要があります。それらをキーマップのキーキャップラベルと考えてください。 + +これらを使うには、`keymap.c` で対応する [ヘッダファイル](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras) を `#include` し、それらで定義されているキーコードを `KC_` プリフィクスの代わりに追加します: + +| レイアウト | ヘッダファイル | +|-----------------------------|----------------------------------| +| Canadian Multilingual (CSA) | `keymap_canadian_multilingual.h` | +| Croatian | `keymap_croatian.h` | +| Czech | `keymap_czech.h` | +| Danish | `keymap_danish.h` | +| Dutch (Belgium) | `keymap_belgian.h` | +| English (Ireland) | `keymap_irish.h` | +| English (UK) | `keymap_uk.h` | +| English (US International) | `keymap_us_international.h` | +| Estonian | `keymap_estonian.h` | +| Finnish | `keymap_finnish.h` | +| French | `keymap_french.h` | +| French (AFNOR) | `keymap_french_afnor.h` | +| French (BÉPO) | `keymap_bepo.h` | +| French (Belgium) | `keymap_belgian.h` | +| French (Switzerland) | `keymap_fr_ch.h` | +| French (macOS, ISO) | `keymap_french_osx.h` | +| German | `keymap_german.h` | +| German (Switzerland) | `keymap_german_ch.h` | +| German (macOS) | `keymap_german_osx.h` | +| German (Neo2)* | `keymap_neo2.h` | +| Greek* | `keymap_greek.h` | +| Hebrew* | `keymap_hebrew.h` | +| Hungarian | `keymap_hungarian.h` | +| Icelandic | `keymap_icelandic.h` | +| Italian | `keymap_italian.h` | +| Italian (macOS, ANSI) | `keymap_italian_osx_ansi.h` | +| Italian (macOS, ISO) | `keymap_italian_osx_iso.h` | +| Japanese | `keymap_jp.h` | +| Korean | `keymap_korean.h` | +| Latvian | `keymap_latvian.h` | +| Lithuanian (ĄŽERTY) | `keymap_lithuanian_azerty.h` | +| Lithuanian (QWERTY) | `keymap_lithuanian_qwerty.h` | +| Norwegian | `keymap_norwegian.h` | +| Polish | `keymap_polish.h` | +| Portuguese | `keymap_portuguese.h` | +| Portuguese (Brazil) | `keymap_br_abnt2.h` | +| Romanian | `keymap_romanian.h` | +| Russian* | `keymap_russian.h` | +| Serbian* | `keymap_serbian.h` | +| Serbian (Latin) | `keymap_serbian_latin.h` | +| Slovak | `keymap_slovak.h` | +| Slovenian | `keymap_slovenian.h` | +| Spanish | `keymap_spanish.h` | +| Spanish (Dvorak) | `keymap_spanish_dvorak.h` | +| Swedish | `keymap_swedish.h` | +| Turkish (F) | `keymap_turkish_f.h` | +| Turkish (Q) | `keymap_turkish_q.h` | + +言語固有でないものもありますが、QWERTY レイアウトを使っていない場合に役立ちます: + +| レイアウト | ヘッダファイル | +|---------------------|--------------------------| +| Colemak | `keymap_colemak.h` | +| Dvorak | `keymap_dvorak.h` | +| Dvorak (French) | `keymap_dvorak_fr.h` | +| Dvorak (Programmer) | `keymap_dvp.h` | +| Norman | `keymap_norman.h` | +| Plover* | `keymap_plover.h` | +| Plover (Dvorak)* | `keymap_plover_dvorak.h` | +| Steno* | `keymap_steno.h` | +| Workman | `keymap_workman.h` | +| Workman (ZXCVM) | `keymap_workman_zxcvm.h` | + +## Sendstring サポート + +デフォルトでは、`SEND_STRING()` は US ANSI キーボードレイアウトが設定されたと見なします。別のレイアウトを使っている場合は、キーマップで(上記のように)`#include "sendstring_*.h"` して、ASCII 文字をキーコードにマッピングするために使われるルックアップテーブルを上書きすることができます。 + +ここで注意すべき重要な点は、`SEND_STRING()` は [ASCII 文字](https://en.wikipedia.org/wiki/ASCII#Character_set) でのみ機能するということです。これは、ユニコード文字を含む文字列を渡すことができないことを意味します - 残念ながら、これには希望のレイアウトに存在する可能性のあるアクセント付き文字が含まれています。 +多くのレイアウトでは、Grave または Tilde などの特定の文字を[デッドキー](https://en.wikipedia.org/wiki/Dead_key)としてのみ使えるようにしています。そのため、デッドキーが次の文字と潜在的に結合されることを防ぐためには、送信したい文字列の中のデッドキーのすぐ後にスペースを追加する必要があります。 +ラテン語由来のアルファベットを使わない(例えば、ギリシャ語やロシア語のような)他のレイアウトには、Sendstring ヘッダーがありません。従って ASCII 文字セットのほとんどを入力する方法がありません。これらは上記で `*` でマークされています。 diff --git a/ja/serial_driver.md b/ja/serial_driver.md new file mode 100644 index 00000000000..72071f4f7ed --- /dev/null +++ b/ja/serial_driver.md @@ -0,0 +1,75 @@ +# 'シリアル' ドライバ + + + +このドライバは[分割キーボード](ja/feature_split_keyboard.md) 機能に使います。 + +?> この文章でのシリアルは、UART/USART/RS485/RS232 規格の実装ではなく、**一度に1ビットの情報を送信するもの**として読まれるべきです。 + +このカテゴリの全てのドライバには以下の特徴があります: +* 1本の線上でデータと信号を提供 +* シングルマスタ、シングルスレーブに限定 + +## サポートされるドライバの種類 + +| | AVR | ARM | +|-------------------|--------------------|--------------------| +| bit bang | :heavy_check_mark: | :heavy_check_mark: | +| USART Half-duplex | | :heavy_check_mark: | + +## ドライバ設定 + +### Bitbang +デフォルトのドライバ。設定がない場合はこのドライバが想定されます。設定するには、以下を rules.mk に追加します: + +```make +SERIAL_DRIVER = bitbang +``` + +config.h を介してドライバを設定します: +```c +#define SOFT_SERIAL_PIN D0 // または D1, D2, D3, E6 +#define SELECT_SOFT_SERIAL_SPEED 1 // または 0, 2, 3, 4, 5 + // 0: 約 189kbps (実験目的のみ) + // 1: 約 137kbps (デフォルト) + // 2: 約 75kbps + // 3: 約 39kbps + // 4: 約 26kbps + // 5: 約 20kbps +``` + +#### ARM + +!> bitbang ドライバは bitbang WS2812 ドライバと接続の問題があります + +上記の一般的なオプションに加えて、halconf.h で `PAL_USE_CALLBACKS` 機能もオンにする必要があります。 + +### USART Half-duplex +通信が USART ハードウェアデバイスに送信される STM32 ボードが対象です。これにより高速で正確なタイミングを提供できることが利点です。このドライバの `SOFT_SERIAL_PIN` は、設定された USART TX ピンです。**TX ピンに適切なプルアップ抵抗が必要です**。設定するには、以下を rules.mk に追加します: + +```make +SERIAL_DRIVER = usart +``` + +config.h を介してハードウェアを設定します: +```c +#define SOFT_SERIAL_PIN B6 // USART TX ピン +#define SELECT_SOFT_SERIAL_SPEED 1 // または 0, 2, 3, 4, 5 + // 0: 約 460800 ボー + // 1: 約 230400 ボー (デフォルト) + // 2: 約 115200 ボー + // 3: 約 57600 ボー + // 4: 約 38400 ボー + // 5: 約 19200 ボー +#define SERIAL_USART_DRIVER SD1 // TX ピンの USART ドライバ。デフォルトは SD1 +#define SERIAL_USART_TX_PAL_MODE 7 // 「代替機能」 ピン。MCU の適切な値については、それぞれのデータシートを見てください。デフォルトは 7 +``` + +また、ChibiOS `SERIAL` 機能を有効にする必要があります: +* キーボードの halconf.h: `#define HAL_USE_SERIAL TRUE` +* キーボードの mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (ここで、'n' は MCU で選択した USART のペリフェラル番号と一致) + +必要な構成は、`UART` 周辺機器ではなく、`SERIAL` 周辺機器であることに注意してください。 diff --git a/ja/support.md b/ja/support.md new file mode 100644 index 00000000000..01c2d41d19c --- /dev/null +++ b/ja/support.md @@ -0,0 +1,22 @@ +# 助けを得る + + + +QMK に関して助けを得るための多くのリソースがあります。 + +コミュニティスペースに参加する前に[行動規範](https://qmk.fm/coc/)を読んでください。 + +## リアルタイムチャット + +何かについて助けが必要な場合は、迅速なサポートを受けるための最良の場所は、[Discord Server](https://discord.gg/Uq7gcHh) です。通常は誰かがオンラインで、非常に助けになる多くの人がいます。 + +## OLKB Subreddit + +公式の QMK フォーラムは [reddit.com](https://reddit.com) の [/r/olkb](https://reddit.com/r/olkb) です。 + +## GitHub Issues + +[GitHub で issue](https://github.com/qmk/qmk_firmware/issues) を開くことができます。issue は長期的な議論あるいはデバッグを必要とする場合は、特に便利です。 diff --git a/ja/syllabus.md b/ja/syllabus.md new file mode 100644 index 00000000000..14e743ee9c4 --- /dev/null +++ b/ja/syllabus.md @@ -0,0 +1,75 @@ +# QMK シラバス + + + +このページは最初に基本を紹介し、そして、QMK に習熟するために必要な全ての概念を理解するように導くことで、QMK の知識を構築するのに役立ちます。 + +# 初級トピック + +他に何も読んでいない場合は、このセクションのドキュメントを読んでください。[QMK 初心者ガイド](ja/newbs.md)を読み終わると、基本的なキーマップを作成し、それをコンパイルし、キーボードに書き込みできるようになっているはずです。残りのドキュメントはこれらの基本的な知識を具体的に肉付けします。 + +* **QMK Tools の使い方を学ぶ** + * [QMK 初心者ガイド](ja/newbs.md) + * [CLI](ja/cli.md) + * [Git](ja/newbs_git_best_practices.md) +* **キーマップについて学ぶ** + * [レイヤー](ja/feature_layers.md) + * [キーコード](ja/keycodes.md) + * 使用できるキーコードの完全なリスト。中級または上級トピックにある知識が必要な場合もあることに注意してください。 +* **IDE の設定** - オプション + * [Eclipse](ja/other_eclipse.md) + * [VS Code](ja/other_vscode.md) + +# 中級トピック + +これらのトピックでは、QMK がサポートする幾つかの機能について掘り下げます。これらのドキュメントを全て読む必要はありませんが、これらの一部をスキップすると、上級トピックのセクションの一部のドキュメントが意味をなさなくなるかもしれません。 + +* **機能の設定方法を学ぶ** + + * [オーディオ](ja/feature_audio.md) + * 電飾 + * [バックライト](ja/feature_backlight.md) + * [LED マトリックス](ja/feature_led_matrix.md) + * [RGB ライト](ja/feature_rgblight.md) + * [RGB マトリックス](ja/feature_rgb_matrix.md) + * [タップホールド設定](ja/tap_hold.md) +* **キーマップについてさらに学ぶ** + * [キーマップ](ja/keymap.md) + * [カスタム関数とキーコード](ja/custom_quantum_functions.md) + * マクロ + * [動的マクロ](ja/feature_dynamic_macros.md) + * [コンパイル済みのマクロ](ja/feature_macros.md) + * [タップダンス](ja/feature_tap_dance.md) + * [コンボ](ja/feature_combo.md) + * [ユーザスペース](ja/feature_userspace.md) + +# 上級トピック + +以下の全ては多くの基礎知識を必要とします。高度な機能を使ってキーマップを作成できることに加えて、`config.h` と `rules.mk` の両方を使ってキーボードのオプションを設定することに慣れている必要があります。 + +* **QMK 内のキーボードの保守** + * [キーボードの手配線](ja/hand_wire.md) + * [キーボードガイドライン](ja/hardware_keyboard_guidelines.md) + * [info.json リファレンス](ja/reference_info_json.md) + * [デバウンス API](ja/feature_debounce_type.md) +* **高度な機能** + * [ユニコード](ja/feature_unicode.md) + * [API](ja/api_overview.md) + * [ブートマジック](ja/feature_bootmagic.md) +* **ハードウェア** + * [キーボードがどのように動作するか](ja/how_keyboards_work.md) + * [キーボードマトリックスの仕組み](ja/how_a_matrix_works.md) + * [分割キーボード](ja/feature_split_keyboard.md) + * [速記](ja/feature_stenography.md) + * [ポインティングデバイス](ja/feature_pointing_device.md) +* **コア開発** + * [コーディング規約](ja/coding_conventions_c.md) + * [互換性のあるマイクロコントローラ](ja/compatible_microcontrollers.md) + * [カスタムマトリックス](ja/custom_matrix.md) + * [QMK を理解する](ja/understanding_qmk.md) +* **CLI 開発** + * [コーディング規約](ja/coding_conventions_python.md) + * [CLI 開発の概要](ja/cli_development.md) diff --git a/ja/tap_hold.md b/ja/tap_hold.md new file mode 100644 index 00000000000..bf23ae4ab0a --- /dev/null +++ b/ja/tap_hold.md @@ -0,0 +1,196 @@ +# タップホールド設定オプション + + + +タップホールドオプションは素晴らしいものですが、問題が無いわけではありません。デフォルト設定を適切なものにしようとしましたが、一部の人にとってまだ問題を引き起こすかもしれません。 + +次のオプションによりタップホールドキーの挙動を変更することができます。 + +## タッピング時間 + +以下の機能の全ての核心は、タッピング時間の設定です。これにより、何をタップとし、何をホールドとするかが決まります。これが自然に感じられるぴったりのタイミングは、キーボードごと、スイッチごと、あるいはキーごとに異ることもありえます。 + +`config.h` に以下の設定を追加することで、この時間を全体的に設定することができます: + +```c +#define TAPPING_TERM 200 +``` + +この設定はミリ秒で定義され、デフォルトは 200ms です。これは大多数の人にとっての適切な平均値です。 + +この機能をより細かく制御するために、以下を `config.h` に追加することができます: +```c +#define TAPPING_TERM_PER_KEY +``` + +そして、以下の関数をキーマップに追加します: + +```c +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SFT_T(KC_SPC): + return TAPPING_TERM + 1250; + case LT(1, KC_GRV): + return 130; + default: + return TAPPING_TERM; + } +} +``` + + +## 許容ホールド + +[PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/) 以降、新しい `config.h` オプションがあります: + +```c +#define PERMISSIVE_HOLD +``` + +これは高速なタイピストや高い `TAPPING_TERM` 設定に対して、タップとホールドキー(モッドタップのような)の動作を向上させます。 + +モッドタップキーを押し、他のキーをタップ(押して放す)して、モッドタップキーを放すという動作の全てをタッピング時間内に行うと、両方のキーのタッピング機能が出力されます。 + +例えば: + +- `SFT_T(KC_A)` を押す +- `KC_X` を押す +- `KC_X` を放す +- `SFT_T(KC_A)` を放す + +通常、これら全てを `TAPPING_TERM` (デフォルト: 200ms) 内で行うと、ファームウェアとホストシステムによって `ax` として登録されます。許容ホールドを有効にすると、別のキーがタップされた場合にモッドタップキーを修飾キーと見なすように処理を変更し、 `X` (`SHIFT`+`x`) と登録されます。 + +?> `モッドタップ割り込みの無視`を有効にしている場合、これにより両方の動きが変更されます。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。 + +この機能をより細かく制御するために、以下を `config.h` に追加することができます: + +```c +#define PERMISSIVE_HOLD_PER_KEY +``` + +そして、以下の関数をキーマップに追加します: + +```c +bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LT(1, KC_BSPC): + return true; + default: + return false; + } +} +``` + +## モッドタップ割り込みの無視 + +この設定を有効にするには、これを `config.h` に追加してください: + +```c +#define IGNORE_MOD_TAP_INTERRUPT +``` + +許容ホールドと同様に、これは高速なタイピストのためのファームウェアの処理方法を変更します。モッドタップキーを押し、他のキーを押し、モッドタップキーを放し、通常のキーを放すと、通常は両方のキーのタッピング機能が出力されます。これはローリングコンボキーには望ましくないかもしれません。 + +`モッドタップ割り込みの無視`を設定するには、両方のキーを `TAPPING_TERM` の間ホールドすると、(その修飾キーの)ホールド機能を実行する必要があります。 + +例えば: + +- `SFT_T(KC_A)` を押す +- `KC_X` を押す +- `SFT_T(KC_A)` を放す +- `KC_X` を放す + +通常、これは `X` (`SHIFT`+`x`) を送信します。`モッドタップ割り込みの無視` を有効にすると、ホールドアクションを登録するには、両方のキーを `TAPPING_TERM` の間ホールドする必要があります。この場合、素早いタップは `ax` を送信しますが、両方をホールドすると、`X` (`SHIFT`+`x`) を出力します。 + + +?> __注意__: これはモディファイアにのみ関係し、レイヤー切り替えキーには関係しません。 + +?> `許容ホールド`を有効にすると、これは両方がどのように動作するかを変更します。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。 + +この機能をより細かく制御するために、以下を `config.h` に追加することができます: + +```c +#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +``` + +そして、以下の関数をキーマップに追加します: + +```c +bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SFT_T(KC_SPC): + return true; + default: + return false; + } +} +``` + +## タッピング強制ホールド + +`タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します: + +```c +#define TAPPING_FORCE_HOLD +``` + +タップの後でユーザがキーをホールドすると、ホールド機能がアクティブになるのではなく、デフォルトでタッピング機能が繰り返されます。これにより、デュアルロールキーのタッピング機能を自動繰り返しする機能を維持することができます。 +`TAPPING_FORCE_HOLD` は、デュアルロールキーをタップした後ホールドした場合、ユーザがホールド機能をアクティブにする機能を削除します。 + +例: + +- `SFT_T(KC_A)` を押す +- `SFT_T(KC_A)` を放す +- `SFT_T(KC_A)` を押す +- タッピング時間が終了するまで待ちます... +- `SFT_T(KC_A)` を放す + +デフォルトの設定では、最初に放したときに `a` が送信され、2回目の押下で `a` が送信され、コンピュータに自動リピート機能を作動させることができます。 + +`TAPPING_FORCE_HOLD` を使うと、2回目の押下は Shift として解釈され、それをタップして使った後ですぐに修飾キーとして使うことができます。 + +!> `TAPPING_FORCE_HOLD` はタッピングトグル(`TT` レイヤーキーコード、ワンショットタップトグルなど)を使うものをすべて破壊します。 + +この機能をより細かく制御するために、以下を `config.h` に追加することができます: + +```c +#define TAPPING_FORCE_HOLD_PER_KEY +``` + +そして、以下の関数をキーマップに追加します: + +```c +bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LT(1, KC_BSPC): + return true; + default: + return false; + } +} +``` + +## レトロタッピング + +`レトロタッピング`を有効にするには、以下を `config.h` に追加してください: + +```c +#define RETRO_TAPPING +``` + +他のキーを押さずにデュアルファンクションキーを押して放しても何も起こりません。レトロタッピングを有効にすると、他のキーを押さずにキーを放すと、元のキーコードがタッピング時間外であっても送信されます。 + +例えば、他のキーを押すことなく `LT(2, KC_SPACE)` を押したり放したりしても何も起こりません。これを有効にすると、代わりに `KC_SPACE` を送信します。 + +## キー別の関数にキーレコードを含めるのはなぜですか? + +「キー別」の関数全てにキーレコードを含んでいることに気付いたかもしれません。そしてなぜそうしたのか不思議に思っているかもしれません。 + +まぁ、それは単純に本当にカスタマイズのためです。ただし、具体的には、それはキーボードの配線方法によって異なります。例えば、各行が実際にキーボードのマトリックスの1行を使っている場合、キーコード全体をチェックする代わりに、`if (record->event.row == 3)` を使うほうが簡単かもしれません。これは、ホームキー行でタップホールドタイプのキーを使っている人にとって特に便利です。そのため、通常のタイピングを妨げないように微調整することができるのではないでしょうか。 + +## `*_kb` や `*_user` 関数が無いのはなぜですか? + +QMK にある他の多くの関数とは異なり、quantum あるいはキーボードレベルの関数を持つ必要はありません (または理由さえありません)。ここではユーザレベルの関数だけが有用なため、そのようにマークする必要はありません。 diff --git a/ja/translating.md b/ja/translating.md new file mode 100644 index 00000000000..f7a273308a6 --- /dev/null +++ b/ja/translating.md @@ -0,0 +1,60 @@ +# QMK ドキュメントを翻訳する + + + +ルートフォルダ (`docs/`) にある全てのファイルは英語でなければなりません - 他の全ての言語は、ISO 639-1 言語コードと、それに続く`-`と関連する国コードのサブフォルダにある必要があります。[一般的なもののリストはここで見つかります](https://www.andiamo.co.uk/resources/iso-language-codes/)。このフォルダが存在しない場合、作成することができます。翻訳された各ファイルは英語バージョンと同じ名前でなければなりません。そうすることで、正常にフォールバックできます。 + +`_summary.md` ファイルはこのフォルダの中に存在し、各ファイルへのリンクのリスト、翻訳された名前、言語フォルダに続くリンクが含まれている必要があります。 + +```markdown + * [QMK简介](zh-cn/getting_started_introduction.md) +``` + +他の docs ページへの全てのリンクにも、言語のフォルダが前に付いている必要があります。もしリンクがページの特定の部分(例えば、特定の見出し)への場合、以下のように見出しに英語の ID を使う必要があります: + +```markdown +[建立你的环境](zh-cn/newbs-getting-started.md#set-up-your-environment) + +## 建立你的环境 :id=set-up-your-environment +``` + +新しい言語の翻訳が完了したら、以下のファイルも修正する必要があります: + +* [`docs/_langs.md`](https://github.com/qmk/qmk_firmware/blob/master/docs/_langs.md) +各行は、[GitHub emoji shortcode](https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#country-flag) の形式で国フラグと、それに続く言語で表される名前を含む必要があります。 + + ```markdown + - [:cn: 中文](/zh-cn/) + ``` + +* [`docs/index.html`](https://github.com/qmk/qmk_firmware/blob/master/docs/index.html) +`placeholder` と `noData` の両方のオブジェクトは、文字列で言語フォルダの辞書エントリが必要です: + + ```js + '/zh-cn/': '没有结果!', + ``` + + サイドバーの「QMK ファームウェア」の見出しリンクを設定するために、`nameLink` オブジェクトも以下のように追加される必要があります: + + ```js + '/zh-cn/': '/#/zh-cn/', + ``` + + また、`fallbackLanguages` リストに言語フォルダを追加して、404 ではなく英語に適切にフォールバックするようにしてください: + + ```js + fallbackLanguages: [ + // ... + 'zh-cn', + // ... + ], + ``` + +## 翻訳のプレビュー + +ドキュメントのローカルインスタンスをセットアップする方法については、[ドキュメントのプレビュー](ja/contributing.md#previewing-the-documentation)を見てください - 右上の "Translations" メニューから新しい言語を選択することができるはずです。 + +作業に満足したら、遠慮なくプルリクエストを開いてください! diff --git a/ja/understanding_qmk.md b/ja/understanding_qmk.md new file mode 100644 index 00000000000..74b37398f84 --- /dev/null +++ b/ja/understanding_qmk.md @@ -0,0 +1,195 @@ +# QMK のコードの理解 + + + +このドキュメントでは、QMK ファームウェアがどのように機能するかを非常に高いレベルから説明しようとしています。基本的なプログラミングの概念を理解していることを前提としていますが、(実例を示す必要がある場合を除き) C に精通していることを前提にはしていません。以下のドキュメントの基本的な知識があることを前提としています。 + +* [入門](ja/getting_started_introduction.md) +* [キーボードがどのように動作するか](ja/how_keyboards_work.md) +* [FAQ](ja/faq.md) + +## スタートアップ + +QMK は他のコンピュータプログラムと何ら変わりないと考えることができます。開始され、タスクを実行し、そして終了します。プログラムのエントリーポイントは、他の C プログラムと同様に、`main()` 関数です。ただし、QMK を初めて触る人は、`main()` 関数が複数の場所に現れるため、混乱するかもしれません。また、どれを見ればよいか分かりにくいかもしれません。 + +複数ある理由は、QMK は様々なプラットフォームをサポートするからです。最も一般的なプラットフォームは `lufa` です。これは atmega32u4 のような AVR プロセッサ上で実行されます。また、`chibios` および `vusb` もサポートします。 + +ここでは AVR プロセッサに焦点を当てます。これは `lufa` プラットフォームを使います。`main()` 関数は [tmk_core/protocol/lufa/lufa.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1028) にあります。関数にざっと目を通すと、(ホストへの USB も含めて)設定された全てのハードウェアが初期化され、プログラムのコア部分が [`while(1)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1069) で開始されることが分かります。これが[メインループ](#the-main-loop)です。 + +## メインループ + +コードのこの部分は、同じ命令セットを永久にループ処理するため、「メインループ」と呼ばれます。ここはキーボードに必要なことを実行させる関数を QMK が呼び出す場所です。一見、多くの機能を持つように見えるかもしれませんが、大抵の場合、コードは `#define` によって無効にされます。 + +``` + keyboard_task(); +``` + +ここで、全てのキーボードの固有の機能が実行されます。`keyboard_task()` のソースコードは [tmk_core/common/keyboard.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/keyboard.c#L216) にあり、マトリックスの変化を検知し、LED の状態をオンオフする責任があります。 + +`keyboard_task()` に以下を処理するコードがあります: + +* [マトリックスのスキャン](#matrix-scanning) +* マウスの処理 +* シリアルリンク +* ビジュアライザ +* キーボードの状態の LED (Caps Lock, Num Lock, Scroll Lock) + +#### マトリックスのスキャン + +マトリックスのスキャンはキーボードファームウェアのコアの機能です。これは今どのキーが押されているかを検知するプロセスであり、キーボードはこの機能を1秒間に何度も何度も実行します。ファームウェアの CPU 時間の 99% はマトリックスのスキャンに費やされていると言っても過言ではありません。 + +実際のマトリックスの検知には様々な方法がありますが、それはこのドキュメントの対象外です。マトリックスのスキャンをブラックボックスとして扱っても問題ありません。マトリックスの現在の状態を求めると、以下のようなデータ構造を取得します: + + +``` +{ + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +これは 4行x5列のテンキー(訳注: 5行x4列の間違いと思われます)のマトリックスを表す直接的な表現のデータ構造です。キーが押されると、マトリックス内のそのキーの位置が、 `0` ではなく `1` として返されます。 + +マトリックスのスキャンは1秒間に何度も実行されます。正確なレートは様々ですが、知覚できるような遅延を避けるために、秒間に少なくとも10回実行します。 + +##### マトリックスから物理的なレイアウトへのマップ + +キーボード上の各スイッチの状態が分かると、それをキーコードへマップする必要があります。QMK ではキーコードへのマップは C マクロを使うことで行われ、C マクロにより物理的なレイアウトの定義はキーコードの定義から分離されています。(訳注:「キーコードの定義」は「キーコードのマトリクス配列による定義」と思われる) + +キーボードレベルで、キーボードのマトリックスを物理キーにマップする C マクロ (一般的には、`LAYOUT()` という名前)を定義します。マトリックスにスイッチがない場所がある場合、このマクロを使って KC_NO を事前に埋め込むことができ、キーマップの定義を扱いやすくすることができます。以下は、テンキー用の `LAYOUT()` マクロです: + +```c +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ +) { \ + { k00, k01, k02, k03, }, \ + { k10, k11, k12, k13, }, \ + { k20, k21, k22, KC_NO, }, \ + { k30, k31, k32, k33, }, \ + { k40, KC_NO, k42, KC_NO } \ +} +``` + +`LAYOUT()` マクロの2つ目のブロックが、上記のマトリックススキャン配列とどのように一致しているかに注目してください。このマクロはマトリックスのスキャン配列をキーコードにマップするものです。ただし、17キーのテンキーを見ると、マトリックスにはスイッチが置けるが、キーが大きいために実際にはスイッチが無い箇所が3つあることが分かります。これらのスペースに `KC_NO` を設定したので、キーマップ定義には必要ありません。 + +このマクロを使って、少し変わったマトリックスのレイアウト、例えば [Clueboard rev 2](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/66/rev2/rev2.h) を扱うこともできます。その説明はこのドキュメントの範囲外です。 + +##### キーコードの割り当て + +キーマップレべルでは、上記の `LAYOUT()` マクロを使って、物理的な場所からマトリックスの場所にマッピングします。以下のようになります: + +``` +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT( + KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \ + KC_P7, KC_P8, KC_P9, KC_PPLS, \ + KC_P4, KC_P5, KC_P6, \ + KC_P1, KC_P2, KC_P3, KC_PENT, \ + KC_P0, KC_PDOT) +} +``` + +これら全ての引数が、前のセクションの `LAYOUT()` マクロの前半とどのように一致しているかについて注目してください。このようにして、キーコードを取得して、それを前述のマトリックススキャンにマップします。 + +##### 状態変更の検知 + +上記のマトリックススキャンはある時点のマトリックスの状態を伝えますが、コンピュータは変更のみを知りたいだけで、現在の状態を気にしません。QMK は最後のマトリックススキャンの結果を格納し、このマトリックスから結果を比較して、いつキーが押されたか放されたかを決定します。 + +例を見てみましょう。キーボードスキャンループの途中に移動して、前のスキャンが以下のようになっていることがわかったとします: + +``` +{ + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +現在のスキャンが完了すると、以下のように見えるとします: + +``` +{ + {1,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +キーマップと比較すると、押されたキーが KC_NLCK であることが分かります。ここから、`process_record` 関数群を呼び出します。 + + + +##### Process Record + +`process_record()` 関数自体は一見簡単に見えますが、その内部は QMK の様々なレベルで機能を上書きするためのゲートウェイが隠されています。キーボード/キーマップレベルの機能について調べる必要があるときは、以下に列挙した一連のイベントを手引帳として使います。`rules.mk` またはほかの場所で設定されたオプションに応じて、最終的なファームウェアに以下の関数のサブセットのみが含まれます。 + +* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/action.c#L172) + * [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L206) + * [このレコードをキーコードにマップする](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L226) + * [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/c1c5922aae7b60b7c7d13d3769350eed9dda17ab/quantum/velocikey.c#L27) + * [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L119) + * [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_key_lock.c#L62) + * [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_clicky.c#L79) + * [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/2cee371bf125a6ec541dd7c5a809573facc7c456/drivers/haptic/haptic.c#L216) + * [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/card.c#L20) + * [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/keymaps/default/keymap.c#L58) + * [`bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/rgb_matrix.c#L139) + * [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_midi.c#L81) + * [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_audio.c#L19) + * [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_steno.c#L160) + * [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_music.c#L114) + * [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L141) + * [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode_common.c#L169) は、以下のいずれかを呼び出します: + * [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode.c#L20) + * [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46) + * [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95) + * [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51) + * [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115) + * [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77) + * [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94) + * [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264) + * [Quantum 固有のキーコードを識別して処理する](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291) + +この一連のイベントの中の任意のステップで (`process_record_kb()` のような)関数は `false` を返して、以降の処理を停止することができます。 + +この呼び出しの後で、`post_process_record()` が呼ばれます。これはキーコードが通常処理された後に実行する必要がある追加のクリーンアップを処理するために使うことができます。 + +* [`void post_process_record(keyrecord_t *record)`]() + * [`void post_process_record_quantum(keyrecord_t *record)`]() + * [このレコードをキーコードにマップする]() + * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]() + * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]() + * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]() + + diff --git a/keycodes.md b/keycodes.md new file mode 100644 index 00000000000..c6403c80bc4 --- /dev/null +++ b/keycodes.md @@ -0,0 +1,564 @@ +# Keycodes Overview + +When defining a [keymap](keymap.md) each key needs a valid key definition. This page documents the symbols that correspond to keycodes that are available to you in QMK. + +This is a reference only. Each group of keys links to the page documenting their functionality in more detail. + +## Basic Keycodes :id=basic-keycodes + +See also: [Basic Keycodes](keycodes_basic.md) + +|Key |Aliases |Description |Windows |macOS |Linux1| +|-----------------------|------------------------------|-----------------------------------------------|-------------|-------------|-----------------| +|`KC_NO` |`XXXXXXX` |Ignore this key (NOOP) |*N/A* |*N/A* |*N/A* | +|`KC_TRANSPARENT` |`KC_TRNS`, `_______` |Use the next lowest non-transparent key |*N/A* |*N/A* |*N/A* | +|`KC_A` | |`a` and `A` |✔ |✔ |✔ | +|`KC_B` | |`b` and `B` |✔ |✔ |✔ | +|`KC_C` | |`c` and `C` |✔ |✔ |✔ | +|`KC_D` | |`d` and `D` |✔ |✔ |✔ | +|`KC_E` | |`e` and `E` |✔ |✔ |✔ | +|`KC_F` | |`f` and `F` |✔ |✔ |✔ | +|`KC_G` | |`g` and `G` |✔ |✔ |✔ | +|`KC_H` | |`h` and `H` |✔ |✔ |✔ | +|`KC_I` | |`i` and `I` |✔ |✔ |✔ | +|`KC_J` | |`j` and `J` |✔ |✔ |✔ | +|`KC_K` | |`k` and `K` |✔ |✔ |✔ | +|`KC_L` | |`l` and `L` |✔ |✔ |✔ | +|`KC_M` | |`m` and `M` |✔ |✔ |✔ | +|`KC_N` | |`n` and `N` |✔ |✔ |✔ | +|`KC_O` | |`o` and `O` |✔ |✔ |✔ | +|`KC_P` | |`p` and `P` |✔ |✔ |✔ | +|`KC_Q` | |`q` and `Q` |✔ |✔ |✔ | +|`KC_R` | |`r` and `R` |✔ |✔ |✔ | +|`KC_S` | |`s` and `S` |✔ |✔ |✔ | +|`KC_T` | |`t` and `T` |✔ |✔ |✔ | +|`KC_U` | |`u` and `U` |✔ |✔ |✔ | +|`KC_V` | |`v` and `V` |✔ |✔ |✔ | +|`KC_W` | |`w` and `W` |✔ |✔ |✔ | +|`KC_X` | |`x` and `X` |✔ |✔ |✔ | +|`KC_Y` | |`y` and `Y` |✔ |✔ |✔ | +|`KC_Z` | |`z` and `Z` |✔ |✔ |✔ | +|`KC_1` | |`1` and `!` |✔ |✔ |✔ | +|`KC_2` | |`2` and `@` |✔ |✔ |✔ | +|`KC_3` | |`3` and `#` |✔ |✔ |✔ | +|`KC_4` | |`4` and `$` |✔ |✔ |✔ | +|`KC_5` | |`5` and `%` |✔ |✔ |✔ | +|`KC_6` | |`6` and `^` |✔ |✔ |✔ | +|`KC_7` | |`7` and `&` |✔ |✔ |✔ | +|`KC_8` | |`8` and `*` |✔ |✔ |✔ | +|`KC_9` | |`9` and `(` |✔ |✔ |✔ | +|`KC_0` | |`0` and `)` |✔ |✔ |✔ | +|`KC_ENTER` |`KC_ENT` |Return (Enter) |✔ |✔ |✔ | +|`KC_ESCAPE` |`KC_ESC` |Escape |✔ |✔ |✔ | +|`KC_BSPACE` |`KC_BSPC` |Delete (Backspace) |✔ |✔ |✔ | +|`KC_TAB` | |Tab |✔ |✔ |✔ | +|`KC_SPACE` |`KC_SPC` |Spacebar |✔ |✔ |✔ | +|`KC_MINUS` |`KC_MINS` |`-` and `_` |✔ |✔ |✔ | +|`KC_EQUAL` |`KC_EQL` |`=` and `+` |✔ |✔ |✔ | +|`KC_LBRACKET` |`KC_LBRC` |`[` and `{` |✔ |✔ |✔ | +|`KC_RBRACKET` |`KC_RBRC` |`]` and `}` |✔ |✔ |✔ | +|`KC_BSLASH` |`KC_BSLS` |`\` and `\|` |✔ |✔ |✔ | +|`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` and `~` |✔ |✔ |✔ | +|`KC_SCOLON` |`KC_SCLN` |`;` and `:` |✔ |✔ |✔ | +|`KC_QUOTE` |`KC_QUOT` |`'` and `"` |✔ |✔ |✔ | +|`KC_GRAVE` |`KC_GRV`, `KC_ZKHK` |` and `~`, JIS Zenkaku/Hankaku|✔ |✔ |✔ | +|`KC_COMMA` |`KC_COMM` |`,` and `<` |✔ |✔ |✔ | +|`KC_DOT` | |`.` and `>` |✔ |✔ |✔ | +|`KC_SLASH` |`KC_SLSH` |`/` and `?` |✔ |✔ |✔ | +|`KC_CAPSLOCK` |`KC_CLCK`, `KC_CAPS` |Caps Lock |✔ |✔ |✔ | +|`KC_F1` | |F1 |✔ |✔ |✔ | +|`KC_F2` | |F2 |✔ |✔ |✔ | +|`KC_F3` | |F3 |✔ |✔ |✔ | +|`KC_F4` | |F4 |✔ |✔ |✔ | +|`KC_F5` | |F5 |✔ |✔ |✔ | +|`KC_F6` | |F6 |✔ |✔ |✔ | +|`KC_F7` | |F7 |✔ |✔ |✔ | +|`KC_F8` | |F8 |✔ |✔ |✔ | +|`KC_F9` | |F9 |✔ |✔ |✔ | +|`KC_F10` | |F10 |✔ |✔ |✔ | +|`KC_F11` | |F11 |✔ |✔ |✔ | +|`KC_F12` | |F12 |✔ |✔ |✔ | +|`KC_PSCREEN` |`KC_PSCR` |Print Screen |✔ |✔2|✔ | +|`KC_SCROLLLOCK` |`KC_SLCK`, `KC_BRMD` |Scroll Lock, Brightness Down (macOS) |✔ |✔2|✔ | +|`KC_PAUSE` |`KC_PAUS`, `KC_BRK`, `KC_BRMU`|Pause, Brightness Up (macOS) |✔ |✔2|✔ | +|`KC_INSERT` |`KC_INS` |Insert |✔ | |✔ | +|`KC_HOME` | |Home |✔ |✔ |✔ | +|`KC_PGUP` | |Page Up |✔ |✔ |✔ | +|`KC_DELETE` |`KC_DEL` |Forward Delete |✔ |✔ |✔ | +|`KC_END` | |End |✔ |✔ |✔ | +|`KC_PGDOWN` |`KC_PGDN` |Page Down |✔ |✔ |✔ | +|`KC_RIGHT` |`KC_RGHT` |Right Arrow |✔ |✔ |✔ | +|`KC_LEFT` | |Left Arrow |✔ |✔ |✔ | +|`KC_DOWN` | |Down Arrow |✔ |✔ |✔ | +|`KC_UP` | |Up Arrow |✔ |✔ |✔ | +|`KC_NUMLOCK` |`KC_NLCK` |Keypad Num Lock and Clear |✔ |✔ |✔ | +|`KC_KP_SLASH` |`KC_PSLS` |Keypad `/` |✔ |✔ |✔ | +|`KC_KP_ASTERISK` |`KC_PAST` |Keypad `*` |✔ |✔ |✔ | +|`KC_KP_MINUS` |`KC_PMNS` |Keypad `-` |✔ |✔ |✔ | +|`KC_KP_PLUS` |`KC_PPLS` |Keypad `+` |✔ |✔ |✔ | +|`KC_KP_ENTER` |`KC_PENT` |Keypad Enter |✔ |✔ |✔ | +|`KC_KP_1` |`KC_P1` |Keypad `1` and End |✔ |✔ |✔ | +|`KC_KP_2` |`KC_P2` |Keypad `2` and Down Arrow |✔ |✔ |✔ | +|`KC_KP_3` |`KC_P3` |Keypad `3` and Page Down |✔ |✔ |✔ | +|`KC_KP_4` |`KC_P4` |Keypad `4` and Left Arrow |✔ |✔ |✔ | +|`KC_KP_5` |`KC_P5` |Keypad `5` |✔ |✔ |✔ | +|`KC_KP_6` |`KC_P6` |Keypad `6` and Right Arrow |✔ |✔ |✔ | +|`KC_KP_7` |`KC_P7` |Keypad `7` and Home |✔ |✔ |✔ | +|`KC_KP_8` |`KC_P8` |Keypad `8` and Up Arrow |✔ |✔ |✔ | +|`KC_KP_9` |`KC_P9` |Keypad `9` and Page Up |✔ |✔ |✔ | +|`KC_KP_0` |`KC_P0` |Keypad `0` and Insert |✔ |✔ |✔ | +|`KC_KP_DOT` |`KC_PDOT` |Keypad `.` and Delete |✔ |✔ |✔ | +|`KC_NONUS_BSLASH` |`KC_NUBS` |Non-US `\` and `\|` |✔ |✔ |✔ | +|`KC_APPLICATION` |`KC_APP` |Application (Windows Context Menu Key) |✔ | |✔ | +|`KC_POWER` | |System Power | |✔3|✔ | +|`KC_KP_EQUAL` |`KC_PEQL` |Keypad `=` |✔ |✔ |✔ | +|`KC_F13` | |F13 |✔ |✔ |✔ | +|`KC_F14` | |F14 |✔ |✔ |✔ | +|`KC_F15` | |F15 |✔ |✔ |✔ | +|`KC_F16` | |F16 |✔ |✔ |✔ | +|`KC_F17` | |F17 |✔ |✔ |✔ | +|`KC_F18` | |F18 |✔ |✔ |✔ | +|`KC_F19` | |F19 |✔ |✔ |✔ | +|`KC_F20` | |F20 |✔ | |✔ | +|`KC_F21` | |F21 |✔ | |✔ | +|`KC_F22` | |F22 |✔ | |✔ | +|`KC_F23` | |F23 |✔ | |✔ | +|`KC_F24` | |F24 |✔ | |✔ | +|`KC_EXECUTE` |`KC_EXEC` |Execute | | |✔ | +|`KC_HELP` | |Help | | |✔ | +|`KC_MENU` | |Menu | | |✔ | +|`KC_SELECT` |`KC_SLCT` |Select | | |✔ | +|`KC_STOP` | |Stop | | |✔ | +|`KC_AGAIN` |`KC_AGIN` |Again | | |✔ | +|`KC_UNDO` | |Undo | | |✔ | +|`KC_CUT` | |Cut | | |✔ | +|`KC_COPY` | |Copy | | |✔ | +|`KC_PASTE` |`KC_PSTE` |Paste | | |✔ | +|`KC_FIND` | |Find | | |✔ | +|`KC__MUTE` | |Mute | |✔ |✔ | +|`KC__VOLUP` | |Volume Up | |✔ |✔ | +|`KC__VOLDOWN` | |Volume Down | |✔ |✔ | +|`KC_LOCKING_CAPS` |`KC_LCAP` |Locking Caps Lock |✔ |✔ | | +|`KC_LOCKING_NUM` |`KC_LNUM` |Locking Num Lock |✔ |✔ | | +|`KC_LOCKING_SCROLL` |`KC_LSCR` |Locking Scroll Lock |✔ |✔ | | +|`KC_KP_COMMA` |`KC_PCMM` |Keypad `,` | | |✔ | +|`KC_KP_EQUAL_AS400` | |Keypad `=` on AS/400 keyboards | | | | +|`KC_INT1` |`KC_RO` |JIS `\` and `_` |✔ | |✔ | +|`KC_INT2` |`KC_KANA` |JIS Katakana/Hiragana |✔ | |✔ | +|`KC_INT3` |`KC_JYEN` |JIS `¥` and `\|` |✔ | |✔ | +|`KC_INT4` |`KC_HENK` |JIS Henkan |✔ | |✔ | +|`KC_INT5` |`KC_MHEN` |JIS Muhenkan |✔ | |✔ | +|`KC_INT6` | |JIS Numpad `,` | | |✔ | +|`KC_INT7` | |International 7 | | | | +|`KC_INT8` | |International 8 | | | | +|`KC_INT9` | |International 9 | | | | +|`KC_LANG1` |`KC_HAEN` |Hangul/English | | |✔ | +|`KC_LANG2` |`KC_HANJ` |Hanja | | |✔ | +|`KC_LANG3` | |JIS Katakana | | |✔ | +|`KC_LANG4` | |JIS Hiragana | | |✔ | +|`KC_LANG5` | |JIS Zenkaku/Hankaku | | |✔ | +|`KC_LANG6` | |Language 6 | | | | +|`KC_LANG7` | |Language 7 | | | | +|`KC_LANG8` | |Language 8 | | | | +|`KC_LANG9` | |Language 9 | | | | +|`KC_ALT_ERASE` |`KC_ERAS` |Alternate Erase | | | | +|`KC_SYSREQ` | |SysReq/Attention | | | | +|`KC_CANCEL` | |Cancel | | | | +|`KC_CLEAR` |`KC_CLR` |Clear | | |✔ | +|`KC_PRIOR` | |Prior | | | | +|`KC_RETURN` | |Return | | | | +|`KC_SEPARATOR` | |Separator | | | | +|`KC_OUT` | |Out | | | | +|`KC_OPER` | |Oper | | | | +|`KC_CLEAR_AGAIN` | |Clear/Again | | | | +|`KC_CRSEL` | |CrSel/Props | | | | +|`KC_EXSEL` | |ExSel | | | | +|`KC_LCTRL` |`KC_LCTL` |Left Control |✔ |✔ |✔ | +|`KC_LSHIFT` |`KC_LSFT` |Left Shift |✔ |✔ |✔ | +|`KC_LALT` |`KC_LOPT` |Left Alt (Option) |✔ |✔ |✔ | +|`KC_LGUI` |`KC_LCMD`, `KC_LWIN` |Left GUI (Windows/Command/Meta key) |✔ |✔ |✔ | +|`KC_RCTRL` |`KC_RCTL` |Right Control |✔ |✔ |✔ | +|`KC_RSHIFT` |`KC_RSFT` |Right Shift |✔ |✔ |✔ | +|`KC_RALT` |`KC_ROPT`, `KC_ALGR` |Right Alt (Option/AltGr) |✔ |✔ |✔ | +|`KC_RGUI` |`KC_RCMD`, `KC_RWIN` |Right GUI (Windows/Command/Meta key) |✔ |✔ |✔ | +|`KC_SYSTEM_POWER` |`KC_PWR` |System Power Down |✔ |✔3|✔ | +|`KC_SYSTEM_SLEEP` |`KC_SLEP` |System Sleep |✔ |✔3|✔ | +|`KC_SYSTEM_WAKE` |`KC_WAKE` |System Wake | |✔3|✔ | +|`KC_AUDIO_MUTE` |`KC_MUTE` |Mute |✔ |✔ |✔ | +|`KC_AUDIO_VOL_UP` |`KC_VOLU` |Volume Up |✔ |✔4|✔ | +|`KC_AUDIO_VOL_DOWN` |`KC_VOLD` |Volume Down |✔ |✔4|✔ | +|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT` |Next Track |✔ |✔5|✔ | +|`KC_MEDIA_PREV_TRACK` |`KC_MPRV` |Previous Track |✔ |✔5|✔ | +|`KC_MEDIA_STOP` |`KC_MSTP` |Stop Track |✔ | |✔ | +|`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY` |Play/Pause Track |✔ |✔ |✔ | +|`KC_MEDIA_SELECT` |`KC_MSEL` |Launch Media Player |✔ | |✔ | +|`KC_MEDIA_EJECT` |`KC_EJCT` |Eject | |✔ |✔ | +|`KC_MAIL` | |Launch Mail |✔ | |✔ | +|`KC_CALCULATOR` |`KC_CALC` |Launch Calculator |✔ | |✔ | +|`KC_MY_COMPUTER` |`KC_MYCM` |Launch My Computer |✔ | |✔ | +|`KC_WWW_SEARCH` |`KC_WSCH` |Browser Search |✔ | |✔ | +|`KC_WWW_HOME` |`KC_WHOM` |Browser Home |✔ | |✔ | +|`KC_WWW_BACK` |`KC_WBAK` |Browser Back |✔ | |✔ | +|`KC_WWW_FORWARD` |`KC_WFWD` |Browser Forward |✔ | |✔ | +|`KC_WWW_STOP` |`KC_WSTP` |Browser Stop |✔ | |✔ | +|`KC_WWW_REFRESH` |`KC_WREF` |Browser Refresh |✔ | |✔ | +|`KC_WWW_FAVORITES` |`KC_WFAV` |Browser Favorites |✔ | |✔ | +|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD` |Next Track |✔ |✔5|✔ | +|`KC_MEDIA_REWIND` |`KC_MRWD` |Previous Track |✔6|✔5|✔ | +|`KC_BRIGHTNESS_UP` |`KC_BRIU` |Brightness Up |✔ |✔ |✔ | +|`KC_BRIGHTNESS_DOWN` |`KC_BRID` |Brightness Down |✔ |✔ |✔ | + +1. The Linux kernel HID driver recognizes [nearly all keycodes](https://github.com/torvalds/linux/blob/master/drivers/hid/hid-input.c), but the default bindings depend on the DE/WM.
+2. Treated as F13-F15.
+3. Must be held for about three seconds, and will display a prompt instead.
+4. Holding Shift+Option allows for finer control of volume level.
+5. Skips the entire track in iTunes when tapped, seeks within the current track when held.
+6. WMP does not recognize the Rewind key, but both alter playback speed in VLC. + +## Quantum Keycodes :id=quantum-keycodes + +See also: [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes) + +|Key |Aliases |Description | +|--------------|---------|-------------------------------------------------------| +|`RESET` | |Put the keyboard into bootloader mode for flashing | +|`DEBUG` | |Toggle debug mode | +|`EEPROM_RESET`|`EEP_RST`|Reinitializes the keyboard's EEPROM (persistent memory)| + +## Audio Keys :id=audio-keys + +See also: [Audio](feature_audio.md) + +|Key |Aliases |Description | +|----------------|---------|----------------------------------| +|`AU_ON` | |Turns on Audio Feature | +|`AU_OFF` | |Turns off Audio Feature | +|`AU_TOG` | |Toggles Audio state | +|`CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode | +|`CLICKY_UP` |`CK_UP` |Increases frequency of the clicks | +|`CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks | +|`CLICKY_RESET` |`CK_RST` |Resets frequency to default | +|`MU_ON` | |Turns on Music Mode | +|`MU_OFF` | |Turns off Music Mode | +|`MU_TOG` | |Toggles Music Mode | +|`MU_MOD` | |Cycles through the music modes | + +## Backlighting :id=backlighting + +See also: [Backlighting](feature_backlight.md) + +|Key |Description | +|---------|------------------------------------------| +|`BL_TOGG`|Turn the backlight on or off | +|`BL_STEP`|Cycle through backlight levels | +|`BL_ON` |Set the backlight to max brightness | +|`BL_OFF` |Turn the backlight off | +|`BL_INC` |Increase the backlight level | +|`BL_DEC` |Decrease the backlight level | +|`BL_BRTG`|Toggle backlight breathing | + +## Bootmagic :id=bootmagic + +See also: [Bootmagic](feature_bootmagic.md) + +|Key |Aliases |Description | +|----------------------------------|---------|--------------------------------------------------------------------------| +|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control | +|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control | +|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control | +|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control | +|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI | +|`MAGIC_UNSWAP_LCTL_LGUI` |`LCG_NRM`|Unswap Left Control and GUI | +|`MAGIC_SWAP_RCTL_RGUI` |`RCG_SWP`|Swap Right Control and GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` |`RCG_NRM`|Unswap Right Control and GUI | +|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Control and GUI on both sides | +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Control and GUI on both sides | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Control and GUI swap on both sides | +|`MAGIC_SWAP_LALT_LGUI` |`LAG_SWP`|Swap Left Alt and GUI | +|`MAGIC_UNSWAP_LALT_LGUI` |`LAG_NRM`|Unswap Left Alt and GUI | +|`MAGIC_SWAP_RALT_RGUI` |`RAG_SWP`|Swap Right Alt and GUI | +|`MAGIC_UNSWAP_RALT_RGUI` |`RAG_NRM`|Unswap Right Alt and GUI | +|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | +|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | +|`MAGIC_NO_GUI` |`GUI_OFF`|Disable the GUI keys | +|`MAGIC_UNNO_GUI` |`GUI_ON` |Enable the GUI keys | +|`MAGIC_SWAP_GRAVE_ESC` |`GE_SWAP`|Swap ` and Escape | +|`MAGIC_UNSWAP_GRAVE_ESC` |`GE_NORM`|Unswap ` and Escape | +|`MAGIC_SWAP_BACKSLASH_BACKSPACE` |`BS_SWAP`|Swap `\` and Backspace | +|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|`BS_NORM`|Unswap `\` and Backspace | +|`MAGIC_HOST_NKRO` |`NK_ON` |Enable N-key rollover | +|`MAGIC_UNHOST_NKRO` |`NK_OFF` |Disable N-key rollover | +|`MAGIC_TOGGLE_NKRO` |`NK_TOGG`|Toggle N-key rollover | +|`MAGIC_EE_HANDS_LEFT` |`EH_LEFT`|Set the master half of a split keyboard as the left hand (for `EE_HANDS`) | +|`MAGIC_EE_HANDS_RIGHT` |`EH_RGHT`|Set the master half of a split keyboard as the right hand (for `EE_HANDS`)| + +## Bluetooth :id=bluetooth + +See also: [Bluetooth](feature_bluetooth.md) + +|Key |Description | +|----------|----------------------------------------------| +|`OUT_AUTO`|Automatically switch between USB and Bluetooth| +|`OUT_USB` |USB only | +|`OUT_BT` |Bluetooth only | + +## Dynamic Macros :id=dynamic-macros + +See also: [Dynamic Macros](feature_dynamic_macros.md) + +|Key |Aliases |Description | +|-----------------|---------|--------------------------------------------------| +|`DYN_REC_START1` |`DM_REC1`|Start recording Macro 1 | +|`DYN_REC_START2` |`DM_REC2`|Start recording Macro 2 | +|`DYN_MACRO_PLAY1`|`DM_PLY1`|Replay Macro 1 | +|`DYN_MACRO_PLAY2`|`DM_PLY2`|Replay Macro 2 | +|`DYN_REC_STOP` |`DM_RSTP`|Finish the macro that is currently being recorded.| + +## Grave Escape :id=grave-escape + +See also: [Grave Escape](feature_grave_esc.md) + +|Key |Aliases |Description | +|-----------|---------|------------------------------------------------------------------| +|`GRAVE_ESC`|`KC_GESC`|Escape when pressed, ` when Shift or GUI are held| + +## Key Lock :id=key-lock + +See also: [Key Lock](feature_key_lock.md) + +|Key |Description | +|---------|--------------------------------------------------------------| +|`KC_LOCK`|Hold down the next key pressed, until the key is pressed again| + +## Layer Switching :id=layer-switching + +See also: [Layer Switching](feature_layers.md#switching-and-toggling-layers) + +|Key |Description | +|----------------|----------------------------------------------------------------------------------| +|`DF(layer)` |Set the base (default) layer | +|`MO(layer)` |Momentarily turn on `layer` when pressed (requires `KC_TRNS` on destination layer)| +|`OSL(layer)` |Momentarily activates `layer` until a key is pressed. See [One Shot Keys](one_shot_keys.md) for details. | +|`LM(layer, mod)`|Momentarily turn on `layer` (like MO) with `mod` active as well. Where `mod` is a mods_bit. Mods can be viewed [here](mod_tap.md). Example Implementation: `LM(LAYER_1, MOD_LALT)`| +|`LT(layer, kc)` |Turn on `layer` when held, `kc` when tapped | +|`TG(layer)` |Toggle `layer` on or off | +|`TO(layer)` |Turns on `layer` and turns off all other layers, except the default layer | +|`TT(layer)` |Normally acts like MO unless it's tapped multiple times, which toggles `layer` on | + +## Leader Key :id=leader-key + +See also: [Leader Key](feature_leader_key.md) + +|Key |Description | +|---------|------------------------| +|`KC_LEAD`|Begins a leader sequence| + +## Mouse Keys :id=mouse-keys + +See also: [Mouse Keys](feature_mouse_keys.md) + +|Key |Aliases |Description | +|----------------|---------|---------------------------| +|`KC_MS_UP` |`KC_MS_U`|Mouse Cursor Up | +|`KC_MS_DOWN` |`KC_MS_D`|Mouse Cursor Down | +|`KC_MS_LEFT` |`KC_MS_L`|Mouse Cursor Left | +|`KC_MS_RIGHT` |`KC_MS_R`|Mouse Cursor Right | +|`KC_MS_BTN1` |`KC_BTN1`|Mouse Button 1 | +|`KC_MS_BTN2` |`KC_BTN2`|Mouse Button 2 | +|`KC_MS_BTN3` |`KC_BTN3`|Mouse Button 3 | +|`KC_MS_BTN4` |`KC_BTN4`|Mouse Button 4 | +|`KC_MS_BTN5` |`KC_BTN5`|Mouse Button 5 | +|`KC_MS_WH_UP` |`KC_WH_U`|Mouse Wheel Up | +|`KC_MS_WH_DOWN` |`KC_WH_D`|Mouse Wheel Down | +|`KC_MS_WH_LEFT` |`KC_WH_L`|Mouse Wheel Left | +|`KC_MS_WH_RIGHT`|`KC_WH_R`|Mouse Wheel Right | +|`KC_MS_ACCEL0` |`KC_ACL0`|Set mouse acceleration to 0| +|`KC_MS_ACCEL1` |`KC_ACL1`|Set mouse acceleration to 1| +|`KC_MS_ACCEL2` |`KC_ACL2`|Set mouse acceleration to 2| + +## Modifiers :id=modifiers + +See also: [Modifier Keys](feature_advanced_keycodes.md#modifier-keys) + +|Key |Aliases |Description | +|----------|-------------------------------|------------------------------------------------------| +|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` | +|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` | +|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` | +|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` | +|`RCTL(kc)`| |Hold Right Control and press `kc` | +|`RSFT(kc)`| |Hold Right Shift and press `kc` | +|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt (AltGr) and press `kc` | +|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` | +|`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)` |Hold Left Shift and GUI and press `kc` | +|`LCA(kc)` | |Hold Left Control and Alt and press `kc` | +|`LSA(kc)` | |Hold Left Shift and Left Alt and press `kc` | +|`RSA(kc)` |`SAGR(kc)` |Hold Right Shift and Right Alt (AltGr) and press `kc` | +|`RCS(kc)` | |Hold Right Control and Right Shift and press `kc` | +|`LCAG(kc)`| |Hold Left Control, Alt and GUI and press `kc` | +|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` | +|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc` | +|`KC_MEH` | |Left Control, Shift and Alt | +|`KC_HYPR` | |Left Control, Shift, Alt and GUI | + +## Mod-Tap Keys :id=mod-tap-keys + +See also: [Mod-Tap](mod_tap.md) + +|Key |Aliases |Description | +|-------------|-----------------------------------------------------------------|--------------------------------------------------------------| +|`MT(mod, kc)`| |`mod` when held, `kc` when tapped | +|`LCTL_T(kc)` |`CTL_T(kc)` |Left Control when held, `kc` when tapped | +|`LSFT_T(kc)` |`SFT_T(kc)` |Left Shift when held, `kc` when tapped | +|`LALT_T(kc)` |`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |Left Alt when held, `kc` when tapped | +|`LGUI_T(kc)` |`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped | +|`RCTL_T(kc)` | |Right Control when held, `kc` when tapped | +|`RSFT_T(kc)` | |Right Shift when held, `kc` when tapped | +|`RALT_T(kc)` |`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt (AltGr) when held, `kc` when tapped | +|`RGUI_T(kc)` |`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped | +|`SGUI_T(kc)` |`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped | +|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped | +|`LSA_T(kc)` | |Left Shift and Left Alt when held, `kc` when tapped | +|`RSA_T(kc)` |`SAGR_T(kc)` |Right Shift and Right Alt (AltGr) when held, `kc` when tapped | +|`RCS_T(kc)` | |Right Control and Right Shift when held, `kc` when tapped | +|`LCAG_T(kc)` | |Left Control, Alt and GUI when held, `kc` when tapped | +|`RCAG_T(kc)` | |Right Control, Alt and GUI when held, `kc` when tapped | +|`C_S_T(kc)` | |Left Control and Shift when held, `kc` when tapped | +|`MEH_T(kc)` | |Left Control, Shift and Alt when held, `kc` when tapped | +|`HYPR_T(kc)` |`ALL_T(kc)` |Left Control, Shift, Alt and GUI when held, `kc` when tapped - more info [here](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)| + +## RGB Lighting :id=rgb-lighting + +See also: [RGB Lighting](feature_rgblight.md) + +|Key |Aliases |Description | +|-------------------|----------|--------------------------------------------------------------------| +|`RGB_TOG` | |Toggle RGB lighting on or off | +|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | +|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held| +|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | +|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | +|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | +|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | +|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | +|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | +|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode | +|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | +|`RGB_MODE_RAINBOW` |`RGB_M_R` |Rainbow animation mode | +|`RGB_MODE_SWIRL` |`RGB_M_SW`|Swirl animation mode | +|`RGB_MODE_SNAKE` |`RGB_M_SN`|Snake animation mode | +|`RGB_MODE_KNIGHT` |`RGB_M_K` |"Knight Rider" animation mode | +|`RGB_MODE_XMAS` |`RGB_M_X` |Christmas animation mode | +|`RGB_MODE_GRADIENT`|`RGB_M_G` |Static gradient animation mode | +|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red,Green,Blue test animation mode | + +## RGB Matrix Lighting :id=rgb-matrix-lighting + +See also: [RGB Matrix Lighting](feature_rgb_matrix.md) + +|Key |Aliases |Description | +|-------------------|----------|--------------------------------------------------------------------------------------| +|`RGB_TOG` | |Toggle RGB lighting on or off | +|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | +|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held | +|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | +|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | +|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | +|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | +|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | +|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | +|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held| +|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held| + +## Thermal Printer :id=thermal-printer + +See also: [Thermal Printer](feature_thermal_printer.md) + +|Key |Description | +|-----------|----------------------------------------| +|`PRINT_ON` |Start printing everything the user types| +|`PRINT_OFF`|Stop printing everything the user types | + +## US ANSI Shifted Symbols :id=us-ansi-shifted-symbols + +See also: [US ANSI Shifted Symbols](keycodes_us_ansi_shifted.md) + +|Key |Aliases |Description| +|------------------------|-------------------|-----------| +|`KC_TILDE` |`KC_TILD` |`~` | +|`KC_EXCLAIM` |`KC_EXLM` |`!` | +|`KC_AT` | |`@` | +|`KC_HASH` | |`#` | +|`KC_DOLLAR` |`KC_DLR` |`$` | +|`KC_PERCENT` |`KC_PERC` |`%` | +|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | +|`KC_AMPERSAND` |`KC_AMPR` |`&` | +|`KC_ASTERISK` |`KC_ASTR` |`*` | +|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | +|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | +|`KC_UNDERSCORE` |`KC_UNDS` |`_` | +|`KC_PLUS` | |`+` | +|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | +|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | +|`KC_PIPE` | |`\|` | +|`KC_COLON` |`KC_COLN` |`:` | +|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | +|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | +|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | +|`KC_QUESTION` |`KC_QUES` |`?` | + +## One Shot Keys :id=one-shot-keys + +See also: [One Shot Keys](one_shot_keys.md) + +|Key |Description | +|------------|----------------------------------| +|`OSM(mod)` |Hold `mod` for one keypress | +|`OSL(layer)`|Switch to `layer` for one keypress| + +## Space Cadet :id=space-cadet + +See also: [Space Cadet](feature_space_cadet.md) + +|Key |Description | +|-----------|----------------------------------------| +|`KC_LCPO` |Left Control when held, `(` when tapped | +|`KC_RCPC` |Right Control when held, `)` when tapped| +|`KC_LSPO` |Left Shift when held, `(` when tapped | +|`KC_RSPC` |Right Shift when held, `)` when tapped | +|`KC_LAPO` |Left Alt when held, `(` when tapped | +|`KC_RAPC` |Right Alt when held, `)` when tapped | +|`KC_SFTENT`|Right Shift when held, Enter when tapped| + +## Swap Hands :id=swap-hands + +See also: [Swap Hands](feature_swap_hands.md) + +|Key |Description | +|-----------|-------------------------------------------------------------------------| +|`SH_T(key)`|Sends `key` with a tap; momentary swap when held. | +|`SW_ON` |Turns on swapping and leaves it on. | +|`SW_OFF` |Turn off swapping and leaves it off. Good for returning to a known state.| +|`SH_MON` |Swaps hands when pressed, returns to normal when released (momentary). | +|`SH_MOFF` |Momentarily turns off swap. | +|`SH_TG` |Toggles swap on and off with every key press. | +|`SH_TT` |Toggles with a tap; momentary when held. | +|`SH_OS` |One shot swap hands: toggle while pressed or until next key press. | + +## Unicode Support :id=unicode-support + +See also: [Unicode Support](feature_unicode.md) + +|Key |Aliases |Description | +|----------------------|---------|----------------------------------------------------------------| +|`UC(c)` | |Send Unicode code point `c` | +|`X(i)` | |Send Unicode code point at index `i` in `unicode_map` | +|`XP(i, j)` | |Send Unicode code point at index `i`, or `j` if Shift/Caps is on| +|`UNICODE_MODE_FORWARD`|`UC_MOD` |Cycle through selected input modes | +|`UNICODE_MODE_REVERSE`|`UC_RMOD`|Cycle through selected input modes in reverse | +|`UNICODE_MODE_MAC` |`UC_M_MA`|Switch to macOS input | +|`UNICODE_MODE_LNX` |`UC_M_LN`|Switch to Linux input | +|`UNICODE_MODE_WIN` |`UC_M_WI`|Switch to Windows input | +|`UNICODE_MODE_BSD` |`UC_M_BS`|Switch to BSD input (not implemented) | +|`UNICODE_MODE_WINC` |`UC_M_WC`|Switch to Windows input using WinCompose | diff --git a/keycodes_basic.md b/keycodes_basic.md new file mode 100644 index 00000000000..09efc8c9c3d --- /dev/null +++ b/keycodes_basic.md @@ -0,0 +1,256 @@ +# Basic Keycodes + +The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07)](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) with the exception of `KC_NO`, `KC_TRNS` and keycodes in the `0xA5-DF` range. See below for more details. + +## Letters and Numbers + +|Key |Description| +|------|-----------| +|`KC_A`|`a` and `A`| +|`KC_B`|`b` and `B`| +|`KC_C`|`c` and `C`| +|`KC_D`|`d` and `D`| +|`KC_E`|`e` and `E`| +|`KC_F`|`f` and `F`| +|`KC_G`|`g` and `G`| +|`KC_H`|`h` and `H`| +|`KC_I`|`i` and `I`| +|`KC_J`|`j` and `J`| +|`KC_K`|`k` and `K`| +|`KC_L`|`l` and `L`| +|`KC_M`|`m` and `M`| +|`KC_N`|`n` and `N`| +|`KC_O`|`o` and `O`| +|`KC_P`|`p` and `P`| +|`KC_Q`|`q` and `Q`| +|`KC_R`|`r` and `R`| +|`KC_S`|`s` and `S`| +|`KC_T`|`t` and `T`| +|`KC_U`|`u` and `U`| +|`KC_V`|`v` and `V`| +|`KC_W`|`w` and `W`| +|`KC_X`|`x` and `X`| +|`KC_Y`|`y` and `Y`| +|`KC_Z`|`z` and `Z`| +|`KC_1`|`1` and `!`| +|`KC_2`|`2` and `@`| +|`KC_3`|`3` and `#`| +|`KC_4`|`4` and `$`| +|`KC_5`|`5` and `%`| +|`KC_6`|`6` and `^`| +|`KC_7`|`7` and `&`| +|`KC_8`|`8` and `*`| +|`KC_9`|`9` and `(`| +|`KC_0`|`0` and `)`| + +## F Keys + +|Key |Description| +|--------|-----------| +|`KC_F1` |F1 | +|`KC_F2` |F2 | +|`KC_F3` |F3 | +|`KC_F4` |F4 | +|`KC_F5` |F5 | +|`KC_F6` |F6 | +|`KC_F7` |F7 | +|`KC_F8` |F8 | +|`KC_F9` |F9 | +|`KC_F10`|F10 | +|`KC_F11`|F11 | +|`KC_F12`|F12 | +|`KC_F13`|F13 | +|`KC_F14`|F14 | +|`KC_F15`|F15 | +|`KC_F16`|F16 | +|`KC_F17`|F17 | +|`KC_F18`|F18 | +|`KC_F19`|F19 | +|`KC_F20`|F20 | +|`KC_F21`|F21 | +|`KC_F22`|F22 | +|`KC_F23`|F23 | +|`KC_F24`|F24 | + +## Punctuation + +|Key |Aliases |Description | +|-----------------|-------------------|-----------------------------------------------| +|`KC_ENTER` |`KC_ENT` |Return (Enter) | +|`KC_ESCAPE` |`KC_ESC` |Escape | +|`KC_BSPACE` |`KC_BSPC` |Delete (Backspace) | +|`KC_TAB` | |Tab | +|`KC_SPACE` |`KC_SPC` |Spacebar | +|`KC_MINUS` |`KC_MINS` |`-` and `_` | +|`KC_EQUAL` |`KC_EQL` |`=` and `+` | +|`KC_LBRACKET` |`KC_LBRC` |`[` and `{` | +|`KC_RBRACKET` |`KC_RBRC` |`]` and `}` | +|`KC_BSLASH` |`KC_BSLS` |`\` and `\|` | +|`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` and `~` | +|`KC_SCOLON` |`KC_SCLN` |`;` and `:` | +|`KC_QUOTE` |`KC_QUOT` |`'` and `"` | +|`KC_GRAVE` |`KC_GRV`, `KC_ZKHK`|` and `~`, JIS Zenkaku/Hankaku| +|`KC_COMMA` |`KC_COMM` |`,` and `<` | +|`KC_DOT` | |`.` and `>` | +|`KC_SLASH` |`KC_SLSH` |`/` and `?` | +|`KC_NONUS_BSLASH`|`KC_NUBS` |Non-US `\` and `\|` | + +## Lock Keys + +|Key |Aliases |Description | +|-------------------|--------------------|------------------------------------| +|`KC_CAPSLOCK` |`KC_CLCK`, `KC_CAPS`|Caps Lock | +|`KC_SCROLLLOCK` |`KC_SLCK`, `KC_BRMD`|Scroll Lock, Brightness Down (macOS)| +|`KC_NUMLOCK` |`KC_NLCK` |Keypad Num Lock and Clear | +|`KC_LOCKING_CAPS` |`KC_LCAP` |Locking Caps Lock | +|`KC_LOCKING_NUM` |`KC_LNUM` |Locking Num Lock | +|`KC_LOCKING_SCROLL`|`KC_LSCR` |Locking Scroll Lock | + +## Modifiers + +|Key |Aliases |Description | +|-----------|--------------------|------------------------------------| +|`KC_LCTRL` |`KC_LCTL` |Left Control | +|`KC_LSHIFT`|`KC_LSFT` |Left Shift | +|`KC_LALT` |`KC_LOPT` |Left Alt (Option) | +|`KC_LGUI` |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) | +|`KC_RCTRL` |`KC_RCTL` |Right Control | +|`KC_RSHIFT`|`KC_RSFT` |Right Shift | +|`KC_RALT` |`KC_ROPT`, `KC_ALGR`|Right Alt (Option/AltGr) | +|`KC_RGUI` |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)| + +## International + +|Key |Aliases |Description | +|----------|---------|---------------------| +|`KC_INT1` |`KC_RO` |JIS `\` and `_` | +|`KC_INT2` |`KC_KANA`|JIS Katakana/Hiragana| +|`KC_INT3` |`KC_JYEN`|JIS `¥` and `\|` | +|`KC_INT4` |`KC_HENK`|JIS Henkan | +|`KC_INT5` |`KC_MHEN`|JIS Muhenkan | +|`KC_INT6` | |JIS Numpad `,` | +|`KC_INT7` | |International 7 | +|`KC_INT8` | |International 8 | +|`KC_INT9` | |International 9 | +|`KC_LANG1`|`KC_HAEN`|Hangul/English | +|`KC_LANG2`|`KC_HANJ`|Hanja | +|`KC_LANG3`| |JIS Katakana | +|`KC_LANG4`| |JIS Hiragana | +|`KC_LANG5`| |JIS Zenkaku/Hankaku | +|`KC_LANG6`| |Language 6 | +|`KC_LANG7`| |Language 7 | +|`KC_LANG8`| |Language 8 | +|`KC_LANG9`| |Language 9 | + +## Commands + +|Key |Aliases |Description | +|------------------|------------------------------|------------------------------| +|`KC_PSCREEN` |`KC_PSCR` |Print Screen | +|`KC_PAUSE` |`KC_PAUS`, `KC_BRK`, `KC_BRMU`|Pause, Brightness Up (macOS) | +|`KC_INSERT` |`KC_INS` |Insert | +|`KC_HOME` | |Home | +|`KC_PGUP` | |Page Up | +|`KC_DELETE` |`KC_DEL` |Forward Delete | +|`KC_END` | |End | +|`KC_PGDOWN` |`KC_PGDN` |Page Down | +|`KC_RIGHT` |`KC_RGHT` |Right Arrow | +|`KC_LEFT` | |Left Arrow | +|`KC_DOWN` | |Down Arrow | +|`KC_UP` | |Up Arrow | +|`KC_APPLICATION` |`KC_APP` |Application (Windows Menu Key)| +|`KC_POWER` | |System Power (macOS/Linux) | +|`KC_EXECUTE` |`KC_EXEC` |Execute | +|`KC_HELP` | |Help | +|`KC_MENU` | |Menu | +|`KC_SELECT` |`KC_SLCT` |Select | +|`KC_STOP` | |Stop | +|`KC_AGAIN` |`KC_AGIN` |Again | +|`KC_UNDO` | |Undo | +|`KC_CUT` | |Cut | +|`KC_COPY` | |Copy | +|`KC_PASTE` |`KC_PSTE` |Paste | +|`KC_FIND` | |Find | +|`KC__MUTE` | |Mute (macOS) | +|`KC__VOLUP` | |Volume Up (macOS) | +|`KC__VOLDOWN` | |Volume Down (macOS) | +|`KC_ALT_ERASE` |`KC_ERAS` |Alternate Erase | +|`KC_SYSREQ` | |SysReq/Attention | +|`KC_CANCEL` | |Cancel | +|`KC_CLEAR` |`KC_CLR` |Clear | +|`KC_PRIOR` | |Prior | +|`KC_RETURN` | |Return | +|`KC_SEPARATOR` | |Separator | +|`KC_OUT` | |Out | +|`KC_OPER` | |Oper | +|`KC_CLEAR_AGAIN` | |Clear/Again | +|`KC_CRSEL` | |CrSel/Props | +|`KC_EXSEL` | |ExSel | + +## Media Keys + +These keycodes are not part of the Keyboard/Keypad usage page. The `SYSTEM_` keycodes are found in the Generic Desktop page, and the rest are located in the Consumer page. + +?> Some of these keycodes may behave differently depending on the OS. For example, on macOS, the keycodes `KC_MEDIA_FAST_FORWARD`, `KC_MEDIA_REWIND`, `KC_MEDIA_NEXT_TRACK` and `KC_MEDIA_PREV_TRACK` skip within the current track when held, but skip the entire track when tapped. + +|Key |Aliases |Description | +|-----------------------|---------|-----------------------------| +|`KC_SYSTEM_POWER` |`KC_PWR` |System Power Down | +|`KC_SYSTEM_SLEEP` |`KC_SLEP`|System Sleep | +|`KC_SYSTEM_WAKE` |`KC_WAKE`|System Wake | +|`KC_AUDIO_MUTE` |`KC_MUTE`|Mute | +|`KC_AUDIO_VOL_UP` |`KC_VOLU`|Volume Up | +|`KC_AUDIO_VOL_DOWN` |`KC_VOLD`|Volume Down | +|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT`|Next Track | +|`KC_MEDIA_PREV_TRACK` |`KC_MPRV`|Previous Track | +|`KC_MEDIA_STOP` |`KC_MSTP`|Stop Track (Windows) | +|`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY`|Play/Pause Track | +|`KC_MEDIA_SELECT` |`KC_MSEL`|Launch Media Player (Windows)| +|`KC_MEDIA_EJECT` |`KC_EJCT`|Eject (macOS) | +|`KC_MAIL` | |Launch Mail (Windows) | +|`KC_CALCULATOR` |`KC_CALC`|Launch Calculator (Windows) | +|`KC_MY_COMPUTER` |`KC_MYCM`|Launch My Computer (Windows) | +|`KC_WWW_SEARCH` |`KC_WSCH`|Browser Search (Windows) | +|`KC_WWW_HOME` |`KC_WHOM`|Browser Home (Windows) | +|`KC_WWW_BACK` |`KC_WBAK`|Browser Back (Windows) | +|`KC_WWW_FORWARD` |`KC_WFWD`|Browser Forward (Windows) | +|`KC_WWW_STOP` |`KC_WSTP`|Browser Stop (Windows) | +|`KC_WWW_REFRESH` |`KC_WREF`|Browser Refresh (Windows) | +|`KC_WWW_FAVORITES` |`KC_WFAV`|Browser Favorites (Windows) | +|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`|Next Track (macOS) | +|`KC_MEDIA_REWIND` |`KC_MRWD`|Previous Track (macOS) | +|`KC_BRIGHTNESS_UP` |`KC_BRIU`|Brightness Up | +|`KC_BRIGHTNESS_DOWN` |`KC_BRID`|Brightness Down | + +## Number Pad + +|Key |Aliases |Description | +|-------------------|---------|------------------------------| +|`KC_KP_SLASH` |`KC_PSLS`|Keypad `/` | +|`KC_KP_ASTERISK` |`KC_PAST`|Keypad `*` | +|`KC_KP_MINUS` |`KC_PMNS`|Keypad `-` | +|`KC_KP_PLUS` |`KC_PPLS`|Keypad `+` | +|`KC_KP_ENTER` |`KC_PENT`|Keypad Enter | +|`KC_KP_1` |`KC_P1` |Keypad `1` and End | +|`KC_KP_2` |`KC_P2` |Keypad `2` and Down Arrow | +|`KC_KP_3` |`KC_P3` |Keypad `3` and Page Down | +|`KC_KP_4` |`KC_P4` |Keypad `4` and Left Arrow | +|`KC_KP_5` |`KC_P5` |Keypad `5` | +|`KC_KP_6` |`KC_P6` |Keypad `6` and Right Arrow | +|`KC_KP_7` |`KC_P7` |Keypad `7` and Home | +|`KC_KP_8` |`KC_P8` |Keypad `8` and Up Arrow | +|`KC_KP_9` |`KC_P9` |Keypad `9` and Page Up | +|`KC_KP_0` |`KC_P0` |Keypad `0` and Insert | +|`KC_KP_DOT` |`KC_PDOT`|Keypad `.` and Delete | +|`KC_KP_EQUAL` |`KC_PEQL`|Keypad `=` | +|`KC_KP_COMMA` |`KC_PCMM`|Keypad `,` | +|`KC_KP_EQUAL_AS400`| |Keypad `=` on AS/400 keyboards| + +## Special Keys + +In addition to these, keycodes in the range of `0xA5-DF` are reserved for internal use by TMK. + +|Key |Aliases |Description | +|----------------|--------------------|---------------------------------------| +|`KC_NO` |`XXXXXXX` |Ignore this key (NOOP) | +|`KC_TRANSPARENT`|`KC_TRNS`, `_______`|Use the next lowest non-transparent key| diff --git a/keycodes_us_ansi_shifted.md b/keycodes_us_ansi_shifted.md new file mode 100644 index 00000000000..85dd61759f8 --- /dev/null +++ b/keycodes_us_ansi_shifted.md @@ -0,0 +1,37 @@ +# US ANSI Shifted Symbols + +These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboard. They do not have keycodes of their own but are simply shortcuts for `LSFT(kc)`, and as such send a Left Shift with the unshifted keycode, not the symbol itself. + +## Caveats + +Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored. + +Additionally, you may run into issues when using Remote Desktop Connection on Windows. Because these codes send shift very fast, Remote Desktop may miss the codes. + +To fix this, open Remote Desktop Connection, click on "Show Options", open the the "Local Resources" tab. In the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly. + +## Keycodes + +|Key |Aliases |Description| +|------------------------|-------------------|-----------| +|`KC_TILDE` |`KC_TILD` |`~` | +|`KC_EXCLAIM` |`KC_EXLM` |`!` | +|`KC_AT` | |`@` | +|`KC_HASH` | |`#` | +|`KC_DOLLAR` |`KC_DLR` |`$` | +|`KC_PERCENT` |`KC_PERC` |`%` | +|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | +|`KC_AMPERSAND` |`KC_AMPR` |`&` | +|`KC_ASTERISK` |`KC_ASTR` |`*` | +|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | +|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | +|`KC_UNDERSCORE` |`KC_UNDS` |`_` | +|`KC_PLUS` | |`+` | +|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | +|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | +|`KC_PIPE` | |`\|` | +|`KC_COLON` |`KC_COLN` |`:` | +|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | +|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | +|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | +|`KC_QUESTION` |`KC_QUES` |`?` | diff --git a/keymap.md b/keymap.md new file mode 100644 index 00000000000..ef476e87f5b --- /dev/null +++ b/keymap.md @@ -0,0 +1,184 @@ +# Keymap Overview + +QMK keymaps are defined inside a C source file. The data structure is an array of arrays. The outer array is a list of layer arrays while the inner layer array is a list of keys. Most keyboards define a `LAYOUT()` macro to help you create this array of arrays. + + +## Keymap and Layers :id=keymap-and-layers +In QMK, **`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`** holds multiple **layers** of keymap information in **16 bit** data holding the **action code**. You can define **32 layers** at most. + +For trivial key definitions, the higher 8 bits of the **action code** are all 0 and the lower 8 bits holds the USB HID usage code generated by the key as **keycode**. + +Respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence. + + Keymap: 32 Layers Layer: action code matrix + ----------------- --------------------- + stack of layers array_of_action_code[row][column] + ____________ precedence _______________________ + / / | high / ESC / F1 / F2 / F3 .... + 31 /___________// | /-----/-----/-----/----- + 30 /___________// | / TAB / Q / W / E .... + 29 /___________/ | /-----/-----/-----/----- + : _:_:_:_:_:__ | : /LCtrl/ A / S / D .... + : / : : : : : / | : / : : : : + 2 /___________// | 2 `-------------------------- + 1 /___________// | 1 `-------------------------- + 0 /___________/ V low 0 `-------------------------- + + +Sometimes, the action code stored in keymap may be referred as keycode in some documents due to the TMK history. + +### Keymap Layer Status :id=keymap-layer-status + +The state of the Keymap layer is determined by two 32 bit parameters: + +* **`default_layer_state`** indicates a base keymap layer (0-31) which is always valid and to be referred (the default layer). +* **`layer_state`** has current on/off status of each layer in its bits. + +Keymap layer '0' is usually the `default_layer`, with other layers initially off after booting up the firmware, although this can configured differently in `config.h`. It is useful to change `default_layer` when you completely switch a key layout, for example, if you want to switch to Colemak instead of Qwerty. + + Initial state of Keymap Change base layout + ----------------------- ------------------ + + 31 31 + 30 30 + 29 29 + : : + : : ____________ + 2 ____________ 2 / / + 1 / / ,->1 /___________/ + ,->0 /___________/ | 0 + | | + `--- default_layer = 0 `--- default_layer = 1 + layer_state = 0x00000001 layer_state = 0x00000002 + +On the other hand, you can change `layer_state` to overlay the base layer with other layers for features such as navigation keys, function keys (F1-F12), media keys, and/or special actions. + + Overlay feature layer + --------------------- bit|status + ____________ ---+------ + 31 / / 31 | 0 + 30 /___________// -----> 30 | 1 + 29 /___________/ -----> 29 | 1 + : : | : + : ____________ : | : + 2 / / 2 | 0 + ,->1 /___________/ -----> 1 | 1 + | 0 0 | 0 + | + + `--- default_layer = 1 | + layer_state = 0x60000002 <-' + + + +### Layer Precedence and Transparency +Note that ***higher layers have higher priority within the stack of layers***. The firmware works its way down from the highest active layers to look up keycodes. Once the firmware locates a keycode other than `KC_TRNS` (transparent) on an active layer, it stops searching, and lower layers aren't referenced. + + ____________ + / / <--- Higher layer + / KC_TRNS // + /___________// <--- Lower layer (KC_A) + /___________/ + + In the above scenario, the non-transparent keys on the higher layer would be usable, but whenever `KC_TRNS` (or equivalent) is defined, the keycode (`KC_A`) on the lower level would be used. + +**Note:** Valid ways to denote transparency on a given layer: +* `KC_TRANSPARENT` +* `KC_TRNS` (alias) +* `_______` (alias) + +These keycodes allow the processing to fall through to lower layers in search of a non-transparent keycode to process. + +## Anatomy of a `keymap.c` + +For this example we will walk through an [older version of the default Clueboard 66% keymap](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c). You'll find it helpful to open that file in another browser window so you can look at everything in context. + +There are 3 main sections of a `keymap.c` file you'll want to concern yourself with: + +* [The Definitions](#definitions) +* [The Layer/Keymap Datastructure](#layers-and-keymaps) +* [Custom Functions](#custom-functions), if any + +### Definitions + +At the top of the file you'll find this: + + #include QMK_KEYBOARD_H + + // Helpful defines + #define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * You can use _______ in place for KC_TRNS (transparent) * + * Or you can use XXXXXXX for KC_NO (NOOP) * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + // Each layer gets a name for readability. + // The underscores don't mean anything - you can + // have a layer called STUFF or any other name. + // Layer names don't all need to be of the same + // length, and you can also skip them entirely + // and just use numbers. + #define _BL 0 + #define _FL 1 + #define _CL 2 + +These are some handy definitions we can use when building our keymap and our custom function. The `GRAVE_MODS` definition will be used later in our custom function, and the following `_BL`, `_FL`, and `_CL` defines make it easier to refer to each of our layers. + +Note: You may also find some older keymap files may also have a define(s) for `_______` and/or `XXXXXXX`. These can be used in place for `KC_TRNS` and `KC_NO` respectively, making it easier to see what keys a layer is overriding. These definitions are now unecessary, as they are included by default. + +### Layers and Keymaps + +The main part of this file is the `keymaps[]` definition. This is where you list your layers and the contents of those layers. This part of the file begins with this definition: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +After this you'll find a list of LAYOUT() macros. A LAYOUT() is simply a list of keys to define a single layer. Typically you'll have one or more "base layers" (such as QWERTY, Dvorak, or Colemak) and then you'll layer on top of that one or more "function" layers. Due to the way layers are processed you can't overlay a "lower" layer on top of a "higher" layer. + +`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard. + +> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode. Some keycode values are reserved to induce execution of certain action codes via the `fn_actions[]` array. + +#### Base Layer + +Here is an example of the Clueboard's base layer: + + /* Keymap _BL: Base Layer (Default Layer) + */ + [_BL] = LAYOUT( + F(0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_BSPC, KC_PGUP, \ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN, \ + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, \ + KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_RSFT, KC_UP, \ + KC_LCTL, KC_LGUI, KC_LALT, KC_MHEN, KC_SPC,KC_SPC, KC_HENK, KC_RALT, KC_RCTL, MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT), + +Some interesting things to note about this: + +* From a C source point of view it's only a single array, but we have embedded whitespace to more easily visualize where each key is on the physical device. +* Plain keyboard scancodes are prefixed with KC_, while "special" keys are not. +* The upper left key activates custom function 0 (`F(0)`) +* The "Fn" key is defined with `MO(_FL)`, which moves to the `_FL` layer while that key is being held down. + +#### Function Overlay Layer + +Our function layer is, from a code point of view, no different from the base layer. Conceptually, however, you will build that layer as an overlay, not a replacement. For many people this distinction does not matter, but as you build more complicated layering setups it matters more and more. + + [_FL] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_DEL, BL_STEP, \ + _______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK, KC_PAUS, _______, _______, _______, _______, \ + _______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ + _______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, \ + _______, _______, _______, _______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END), + +Some interesting things to note: + +* We have used our `_______` definition to turn `KC_TRNS` into `_______`. This makes it easier to spot the keys that have changed on this layer. +* While in this layer if you press one of the `_______` keys it will activate the key in the next lowest active layer. + +# Nitty Gritty Details + +This should have given you a basic overview for creating your own keymap. For more details see the following resources: + +* [Keycodes](keycodes.md) +* [Keymap FAQ](faq_keymap.md) + +We are actively working to improve these docs. If you have suggestions for how they could be made better please [file an issue](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/ko-kr/README.md b/ko-kr/README.md new file mode 100644 index 00000000000..881b4b5aced --- /dev/null +++ b/ko-kr/README.md @@ -0,0 +1,33 @@ +# Quantum Mechanical Keyboard Firmware + +[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## QMK Firmware 란? + +QMK(*Quantum Mechanical Keyboard 양자 기계식 키보드*)란 QMK 컴워어, QMK 툴박스, qmk.fm 를 관리하고 있는 오픈소스 커뮤니티 입니다. QMK펌웨어는 [tmk\_keyboard](http://github.com/tmk/tmk_keyboard)를 바탕으로 만들어진 키보드펌웨어이며, Atmel AVR컨트롤러와 [OLKB 제품군](http://olkb.com) [ErgoDox EZ](http://www.ergodox-ez.com), 그리고 [Clueboard 제품군](http://clueboard.co/) 이용할때 매우 편리합니다. 또한 QMK는 ChibiOS를 사용하여 ARM기반의 컨트롤러로도 사용할수 있습니다. 마지막으로 QMK는 커스텀회로와 핸드와이어드 키보드을 작동시키는데에도 사용가능합니다. + + +## 설치하기 + +만약 당신이 QMK에 키보드, 키맵, 또는 새로운 기능을 추가하고싶다면, 가장쉬운 방법은 Github를 통해 [저장소(REPO)를 추가하고]((https://github.com/qmk/qmk_firmware#fork-destination-box)) 로컬에서 변화 또는 수정하고, [PULL REQUEST](https://github.com/qmk/qmk_firmware/pulls)을 통해 업로드 할수 있습니다. + +또다른 방법으로는, 직접 파일들 로컬로 다운로드 하거나([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), git (`git@github.com:qmk/qmk_firmware.git`), https (`https://github.com/qmk/qmk_firmware.git`)을 통해 클론을 만들수 있습니다. + +## 컴파일 + +먼저 컴파일을 하기전 AVR 이나 ARM [개발환경](getting_started_build_tools.md)을 구축해야 합니다. 모든준비가 끝났다면 `make`를 다음과 같이 키보드와 키맵을 선택하여 컴파일 할 수 있습니다. + + make planck/rev4:default + +이 커맨드는 `rev4`버전의 `planck`를 `default`키맵으로 컴파일 할것입니다. 다만 모든 키보드는 파일, 수정본 또는 세부프로젝트를 가지고있지 않음으로 수정본 부분을 생략될수 있습니다. + + make preonic:default + +## 커스터마이징 + +QMK는 사용할 수 있는 매우 다양한 [기능](features.md)과 체계화된 [참고자료](http://docs.qmk.fm)들이 있습니다. 그중 대부분은 [키맵](keymap.md)을 수정하거나 [키코드](keycodes.md)를 변경하는데에 특화되어 있습니다. diff --git a/ko-kr/getting_started_build_tools.md b/ko-kr/getting_started_build_tools.md new file mode 100644 index 00000000000..3aae69d25d9 --- /dev/null +++ b/ko-kr/getting_started_build_tools.md @@ -0,0 +1,156 @@ +# 컴파일 도구 설치 + +이 페이지는 QMK 컴파일 환경을 설치하는 방법을 설명합니다. 이 페이지는 AVR 프로세서들(예를 들면 atmega32u4와 비슷한)을 위한 가이드를 제공합니다 + + + + +**노트:** 만약 당신이 처음 시작한다면 [입문자를 위한 가이드](newbs.md)페이지를 확인하세요. + +계속하기전에 당신의 서브모듈(외부라이브러리)이 최신인지 `make git-submodule`을 사용하여 확인하세요. + +## 리눅스 + +당신이 항상 최신 파일을 가지고 있는지는 `sudo util/qmk_install.sh`을 이용하여 간단히 확인할 수 있습니다. 이 명령어는 당신이 필요한 모든 속성물(dependencies)를 설치할 것입니다. **이 명령어는 `apt-get upgrade`를 사용합니다** + +또한 당신의 직접 필요한 것들을 설치할 수도 있습니다. 하지만 이 자료는 항상 최신의 자료을 가지고 있지 않습니다. + +현재로써 필요한 것은 다음과 같습니다. 하지만 당신이 하는 작업에 따라 당신은 다음 패키지를 다 쓰지 않을 수도 있습니다. 또한 환경에 따라 모든 다음 패키지는 다른이름으로 존재하거나, 없을 수도 있습니다. + +``` +build-essential +gcc +unzip +wget +zip +gcc-avr +binutils-avr +avr-libc +dfu-programmer +dfu-util +gcc-arm-none-eabi +binutils-arm-none-eabi +libnewlib-arm-none-eabi +git +``` + +당신이 사용하는 패키지 매니져에서 이러한 방법으로 설치하십시요. + +데비안 / 우분투 예시: + + sudo apt-get update + sudo apt-get install gcc unzip wget zip gcc-avr binutils-avr avr-libc dfu-programmer dfu-util gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi + +페도라 / 레드햇 예시: + + sudo dnf install gcc unzip wget zip dfu-util dfu-programmer avr-gcc avr-libc binutils-avr32-linux-gnu arm-none-eabi-gcc-cs arm-none-eabi-binutils-cs arm-none-eabi-newlib + +아치 / 맨자로(Manjaro) 예시: + + pacman -S base-devel gcc unzip wget zip avr-gcc avr-binutils avr-libc dfu-util arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib git dfu-programmer dfu-util + +## 닉스 (NIX) + +만약 당신이 [NixOS](https://nixos.org/)를 사용중이거나 NIX를 리눅스 또는 맥에서 사용중이라면 `nix-shell`를 root 디렉토리에서 사용하여 컴파일 환경의 구축할 수 있습니다. + +기본적으로 다음 커맨드는 AVR과 ARM 컴파일러를 설치할것입니다. 만약 필요 없다면 `avr` 또는 `arm`을 인수에서 해제할 수 있습니다. + + nix-shell --arg arm false + +## 맥 +당신이 홈브루([homebrew](http://brew.sh/))를 사용한다면, 다음을 입력하세요. + + brew tap osx-cross/avr + brew tap PX4/homebrew-px4 + brew update + brew install avr-gcc@7 + brew link --force avr-gcc@7 + brew install dfu-programmer + brew install dfu-util + brew install gcc-arm-none-eabi + brew install avrdude + +이 방법을 가장 추천합니다. 만약 홈브루가 없다면 커맨드라인 환경에서 매우 편한 [Homebrew](http://brew.sh/)를 다운받는 것을 추천합니다. 참고로 `avr-gcc@7`를 설치하는 중 `make`과 `make install`는 대개 20분 넘게 걸리고 CPU 사용량이 높아집니다. + +## msys2를 사용하는 윈도우 (추천) +윈도우 비스타 부터 최신버젼까지 가장추천되는 환경은 [msys2](http://www.msys2.org)를 이용하는 것입니다. (윈도우 7과 윈도우 10에서 모두 테스트되었음) + +* 이 사이트에 있는 설명을 이용해 msys2를 설치하세요: http://www.msys2.org +* ``MSYS2 MingGW 64-bit`` 를 여세요 +* QMK폴더로 이동하세요. c드라이브 루트에 있는경우: + * `$ cd /c/qmk_firmware` +* `util/qmk_install.sh`을 실행시키고 나오는데요 따라하세요 + +### 크리에이터 업데이트 +만약 당신의 윈도우 10이 크리에이터 업데이트 버전 또는 더 높은 버전이라면 바로 컴파일과 프로그램 업로드(flashing)를 할 수 있습니다. 크리에이터 업데이트 전 버전이라면 컴파일만 가능합니다. 만약 당신이 잘 모르겠거나 업데이트된 버전이 아니라면 [이 링크](https://support.microsoft.com/en-us/instantanswers/d4efb316-79f0-1aa1-9ef3-dcada78f3fa0/get-the-windows-10-creators-update)를 확인해 보십시오. + +### 리눅스용 윈도우 하위 시스템 사용 (Windows10 Subsystem for Linux) +크리에이터 업데이트에 추가로 만약 당신이 리눅스용 윈도우 하위 시스템이 필요하다면 이 링크에서 다운받으십시오: [설명](http://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/) + +만약 당신이 이미 리눅스용 윈도우 하위 시스템을 Anniversary업데이트를 통해 받았다면 이 링크에서 16.04LTS로 업데이트 하는것을 추천합니다. 왜냐하면 업데이트 없이는 일부키보드가 14.04LTS에 포함되있는 도구들로 컴파일되지 않을수 있기때문입니다 : [WSL 업데이트](https://betanews.com/2017/04/14/upgrade-windows-subsystem-for-linux/) + + +### Git +만약 당신이 이미 파일을 로컬로 복제하였다면 이 섹션을 무시하십시요. + +당신은 파일을 기본적인 git을 사용하여 로컬로 복제해야 합니다. **주의, WSL Git을 사용하면 안됩니다** [Git](https://git-scm.com/download/win) 이 링크에서 git을 다운받고 설치하십시오. +그리고 [기본설정](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup), 유저네임과 이메일을 설정하는 것은 만약 당신이 온라인에 기여할 계획이라면 매우 중요합니다. + +Git의 설치가 완료되었다면 Git Bash커맨드을 열고 당신의 복제 QMK파일이 있는 위치로 이동하고 `git clone --recurse-submodules https://github.com/qmk/qmk_firmware`를 실행 시키십니오. 이 커맨드는 새로운 `qmk_firmware`폴더를 이미 존재하는 것의 하위 폴더설정으로 생성할 것입니다. + +### 도구(Toolchain) 설정 +기본적으로 도구설정은 리눅스용 윈도우 하위 시스템이 설치될때 자동으로 설정됩니다. 하지만 수동적으로 하고 싶다면 여기 설명이 있습니다. (If you want to do everything manually, there are no other instructions than the scripts themselves, but you can always open issues and ask for more information. ) + +1. "Bash On Ubuntu On Windows" 을 실행시키십시오. +2. 당신이 `qmk_firmware`를 복제한 위치로 가십시오. WSL(리눅스용 윈도우 하위 시스템 사용)에서 `/mnt/`로 시작되는 패스를 찾으십시오. 즉 당신은 다음과 같은 형식으로 입력해야 합니다. `cd /mnt/c/path/to/qmk_firmware` (Note that the paths start with `/mnt/`in the WSL, so you have to write for example `cd /mnt/c/path/to/qmk_firmware`.) +3. `util/wsl_install.sh`를 실행시키고 화면에 나오는 지시를 따르십니오. +4. Bash command window를 재실행 시키십시오. +5. 이로써 당신은 컴파일과 프로그램 업로드(flashing)을 위한 준비가 모두 끝났습니다. + +### 중요한 참고사항 +*`util/wsl_install.sh` 명령어를 다시 실행시켜 최신 업데이트를 다운받을 수 있습니다. +* QMK 폴더의 위치는 윈도우 파일시스템을 기반으로 해야 됩니다. WSL는 외부실행파일를 작동 시킬수 없기 때문이죠. +* WSL의 Git은 윈도우용 Git과 **호환되지 않습니다** +* 파일을 수정하는 것은 WSL안과 밖에서 모두 가능합니다 하지만 만약 .makefile 혹은 .sh를 수정한다면 유닉스 라인엔딩(Unix line endings)을 지원하는 에디터를 사용하는지 확인하십이오. 그렇지 않다면 컴파일이 되지않을 수도 있습니다. + +## 윈두우 (비스타 혹은 더 최신) (비추천) + +이 섹션은 윈도우 비스타 혹은 더 최신버젼을 위한 오래된 설명입니다. [MSYS2](#windows-with-msys2-recommended)를 사용하는 것을 더 추천합니다. + +1. WinAVR을 설치하였다면 먼저 삭제하십시오. +2. [MHV AVR Tools](https://infernoembedded.com/sites/default/files/project/MHV_AVR_Tools_20131101.exe)을 설치하십시오. (Disable smatch, but **be sure to leave the option to add the tools to the PATH checked**) +3. 만약 당신이 Infinity을 기반으로 하는 키보드에 프로그램 업로드를(flashing) 할거라면 dfu-util을 설치해야 합니다, [Input Club](https://github.com/kiibohd/controller/wiki/Loading-DFU-Firmware) 를 참고 하십시오. +4. [MinGW](https://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download)를 설치하십시오. 설치중 윈도우화면에서 GUI 추가 설치 옵션을 해재하십니오. **기본 설치 위치를 바꾸지 마십시오.** 이 명령어는 기본위치를 기반으로 하고 있습니다. +5. 레파지토리를 복제하십시오. [이 링크로 압축파일을 받고 앞축해제 하십시오.](https://github.com/qmk/qmk_firmware/archive/master.zip) 윈도우 탐색기에서 다운받은 파일을 여십시오. +6. `\util` 폴더를 여십시오. +7. `1-setup-path-win` .bat파일을 더블클릭해서 실행시키시오. 유저 계정 설정 변경을 허용해야될 수도 있습니다. 스페이스바를 눌러 설치가 성공적으로 완료되었다는 메세지를 닫을 수 있습니다. +8. `2-setup-environment-win` .bat파일에 우클릭해서 '관리자 권한으로 실행'으로 실행시키십시오. 이 작업을 꽤 오래 걸릴 수도 있습니다. 또한 드라이버 설정을 승인해야 될 수도 있습니다. 하지만 이 모든것이 끝나면 당신의 시스템의 설정이 모두 끝났습니다. + +만약 이 작업을 하는데에 문제가 있어 도움받고 싶다면 *Win_Check_Output.txt*을 생성하는 것이 도움이 될것입니다. 이 파일은 `Win_Check.bat`을 `\util`폴더에서 실행시켜 생성할 수 있습니다. + +## 도커(Docker) +만약 위작업들이 당신에게 좀 어렵게 느껴졌다면 도커(Docker)가 당신을 위한 최선일 수도 있습니다(의역). [Docker CE](https://docs.docker.com/install/#supported-platforms)를 설치한뒤 아래 커맨드를 `qmk_firmware` 디랙토리에서 실행시켜 키보드 또는 키맵을 생성시킵니다. +```bash +util/docker_build.sh keyboard:keymap +# 예: util/docker_build.sh ergodox_ez:steno +``` +이 커맨드는 원하는 키보드 또는 키맵을 컴파일하고 `.hex`또는 `.bin`파일을 프로그램 업로드를(flashing) 위해 QMK디랙토리에 생성할것입니다. 만약 `:keymap`이 생략된다면 `default`이 기본을로 사용됩니다. 참고로 여기서 사용되는 인수는 `make` 커맨드를 사용하여 컴파일할때와 동일합니다. + + +또한 스크립트를 그냥 아무 인수 없이도 사용가능합니다. 그렇게 된다면 프로그램은 하나씩 자동으로 인수입력을 요구 할것입니다. 어쩌면 이방법이 더 쉬울 수도 있습니다. +```bash +util/docker_build.sh +# 인수을 입력받습니다.(아무것도 쓰지 않고 놔두는면 기본값으로 설정됩니다) +``` + +다음과 같이 `target`를 사용하여 컴파일과 프로그램 업로드(flashing)을 동시에 할수도 있습니다. +```bash +util/docker_build.sh keyboard:keymap:target +# 예: util/docker_build.sh planck/rev6:default:dfu-util +``` +만약 당시이 리눅스를 사용한다면 이 커맨드들은 추가 설정 없이 바로 작동할 것입니다. 하지만 위도우 또는 맥 환경에서는 [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/)를 사용하여야 이 커맨드들을 사용가능합니다. Docker Machine설정은 꽤 지루하고 짜증남으로 추천하지 않고 [QMK Toolbox](https://github.com/qmk/qmk_toolbox)를 사용하는 것을 추천합니다. + +!> 윈도우에서 독커는 [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)을 활성화 설정하여야 사용가능합니다. 즉, 도커는 Hyper-V를 지원하지 않는 윈도우 7, 윈도우 8, 그리고 **윈도우 10 홈**과 같은 윈도우 버전에서 사용할수 없다는 것을 의미합니다. + +## Vagrant +만약 컴웨어를 사용하는데 문제가 있다면 Vagrant라는 이름의 툴을 사용해 볼 수 있습니다. 이 툴은 가상환경을 세팅해줌과 동시에 컴웨어를 사용하는데에 필요한 모든 설정을 해줄 것입니다. OLKB는 가상환경에 파일을 호스팅하지 않습니다. [Vagrant 가이드](getting_started_vagrant.md)에서 더 많은 정보를 확인할 수 있습니다. diff --git a/ko-kr/getting_started_getting_help.md b/ko-kr/getting_started_getting_help.md new file mode 100644 index 00000000000..2ae7917a015 --- /dev/null +++ b/ko-kr/getting_started_getting_help.md @@ -0,0 +1,17 @@ +# 도움 받기 + +QMK에서 도움을 받는 방법은 다양합니다. + +**주의, 아래 링크들은 영어로 이루어져 있으며 영어 사용이 가능해야 편리하게 이용할 수 있습니다.** + +## 디스코드 실시간 채팅 + +[QMK 디스코드 서버](https://discord.gg/Uq7gcHh)에서 QMK 개발자들과 실시간으로 대화를 나눌수있습니다. 이 디스코드에는 펌웨어, 툴박스, 하드웨어, 그리고 컨피겨레이터(configurator)에 관한 특별화된 채널이 운영되고 있습니다. + +## OLKB 서브레딧 + +공식 QMK 포럼은 [reddit.com](https://reddit.com) 에 [/r/olkb](https://reddit.com/r/olkb)입니다. + +## Github 이슈 + +[issue on GitHub](https://github.com/qmk/qmk_firmware/issues)에서 문제를 보고 할 수 있습니다. 이 링크는 문제가 오랜 시간을 필요로하거나 디버깅를 요구 할때 매우 유용합니다. diff --git a/ko-kr/getting_started_github.md b/ko-kr/getting_started_github.md new file mode 100644 index 00000000000..2ff0ccb7968 --- /dev/null +++ b/ko-kr/getting_started_github.md @@ -0,0 +1,67 @@ +# QMK와 함께 Github를 사용하는 방법 + +Github can be a little tricky to those that aren't familiar with it - this guide will walk through each step of forking, cloning, and submitting a pull request with QMK. + +Github는 자주 사용하는 사람이 아니면 좀 여려울수도 있습니다. 이 문서는 Github를 사용하는데 필요한 forking, cloning 그리고 submitting a pull request with QMK를 설명할 것입니다. + +?> 이 가이드는 당신이 git커맨드를 사용하는데 익숙하고 git환경을 당신의 시스템이 설치하였다는 전제하에 작성되었습니다. + +아래와 같이 [QMK Github 페이지](https://github.com/qmk/qmk_firmware)에서 당신은 "Fork"라고 쓰여있는 버튼을 볼 수 있습니다 + +![Fork on Github](http://i.imgur.com/8Toomz4.jpg) + +만약 당신이 어느기관 소속이고, 무슨 계정을 사용할것인지 골라야 한다면 개인 계정을 사용하는 것을 추천합니다. +"Fork"가 성공적으로 끝났다면 아래 보이는 "Clone or Download"를 눌러야 합니다. + +![Download from Github](http://i.imgur.com/N1NYcSz.jpg) + +"HTTPS"채크 했는지 확인하고 나와 있는 링크를 복사하세요. + +![HTTPS link](http://i.imgur.com/eGO0ohO.jpg) + +여기거 부터 커맨드라인을 사용합니다. 커맨드 라인에서 `git clone `을 치고 복사한 링크를 붙여넣은후 실행시키세요. + +``` +user@computer:~$ git clone https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Counting objects: 46625, done. +remote: Compressing objects: 100% (2/2), done. +remote: Total 46625 (delta 0), reused 0 (delta 0), pack-reused 46623 +Receiving objects: 100% (46625/46625), 84.47 MiB | 3.14 MiB/s, done. +Resolving deltas: 100% (29362/29362), done. +Checking out files: 100% (2799/2799), done. +``` + +당신은 이제 모든파일이 로컬시스템이 추가 되었습니다 그리고 이제 키맵을 추가하거나 컴파일, 프로그램 업로드(flashing)를 할 수 있습니다. +모든 추가 변경을 만든 뒤에는 add, commit, and push를 사용하여 당신의 Folk에 추가 할 수 있습니다. + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +이로써 당신이 만든 모든 변경들이 당신의 Github의 Folk에 추가 되었습니다. (`https://github.com//qmk_firmware`)에서 확인하고 "New Pull Request"를 눌러 변경사항을 QMK에 업로드할수 있습니다. + +![New Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +이 버튼을 누르면 당신이 만든 모든 변경사항들이 보여질 것입니다. 만약 모든 변경사항이 맘에 든다면 "Create Pull Request"를 눌러 요청을 확정할수 있습니다. + +**요청사항이 확정된다고 변경사항이 바로 적용되는 것은 아닙니다.** + +![Create Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +요청을 한뒤 QMK개발자들은 댓글로 무엇이 변경되었는지 등을 물어 볼수있지만 끝에는 매인 디랙토리로 업로드 될것입니다. + +**"Thanks for contributing to QMK :)"** diff --git a/mod_tap.md b/mod_tap.md new file mode 100644 index 00000000000..0dc35ff034c --- /dev/null +++ b/mod_tap.md @@ -0,0 +1,61 @@ +# Mod-Tap + +The Mod-Tap key `MT(mod, kc)` acts like a modifier when held, and a regular keycode when tapped. In other words, you can have a key that sends Escape when you tap it, but functions as a Control or Shift key when you hold it down. + +The modifiers this keycode and `OSM()` accept are prefixed with `MOD_`, not `KC_`: + +|Modifier |Description | +|----------|----------------------------------------| +|`MOD_LCTL`|Left Control | +|`MOD_LSFT`|Left Shift | +|`MOD_LALT`|Left Alt | +|`MOD_LGUI`|Left GUI (Windows/Command/Meta key) | +|`MOD_RCTL`|Right Control | +|`MOD_RSFT`|Right Shift | +|`MOD_RALT`|Right Alt (AltGr) | +|`MOD_RGUI`|Right GUI (Windows/Command/Meta key) | +|`MOD_HYPR`|Hyper (Left Control, Shift, Alt and GUI)| +|`MOD_MEH` |Meh (Left Control, Shift, and Alt) | + +You can combine these by ORing them together like so: + +```c +MT(MOD_LCTL | MOD_LSFT, KC_ESC) +``` + +This key would activate Left Control and Left Shift when held, and send Escape when tapped. + +For convenience, QMK includes some Mod-Tap shortcuts to make common combinations more compact in your keymap: + +|Key |Aliases |Description | +|------------|-----------------------------------------------------------------|--------------------------------------------------------------| +|`LCTL_T(kc)`|`CTL_T(kc)` |Left Control when held, `kc` when tapped | +|`LSFT_T(kc)`|`SFT_T(kc)` |Left Shift when held, `kc` when tapped | +|`LALT_T(kc)`|`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |Left Alt when held, `kc` when tapped | +|`LGUI_T(kc)`|`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped | +|`RCTL_T(kc)`| |Right Control when held, `kc` when tapped | +|`RSFT_T(kc)`| |Right Shift when held, `kc` when tapped | +|`RALT_T(kc)`|`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt when held, `kc` when tapped | +|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped | +|`SGUI_T(kc)`|`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped | +|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped | +|`LSA_T(kc)` | |Left Shift and Alt when held, `kc` when tapped | +|`RSA_T(kc)` |`SAGR_T(kc)` |Right Shift and Right Alt (AltGr) when held, `kc` when tapped | +|`RCS_T(kc)` | |Right Control and Right Shift when held, `kc` when tapped | +|`LCAG_T(kc)`| |Left Control, Alt and GUI when held, `kc` when tapped | +|`RCAG_T(kc)`| |Right Control, Alt and GUI when held, `kc` when tapped | +|`C_S_T(kc)` | |Left Control and Shift when held, `kc` when tapped | +|`MEH_T(kc)` | |Left Control, Shift and Alt when held, `kc` when tapped | +|`HYPR_T(kc)`|`ALL_T(kc)` |Left Control, Shift, Alt and GUI when held, `kc` when tapped - more info [here](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)| + +## Caveats + +Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored. + +Additionally, you may run into issues when using Remote Desktop Connection on Windows. Because these codes send shift very fast, Remote Desktop may miss the codes. + +To fix this, open Remote Desktop Connection, click on "Show Options", open the the "Local Resources" tab. In the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly. + +## Other Resources + +See the [Tap-Hold Configuration Options](tap_hold.md) for additional flags that tweak Mod-Tap behavior. diff --git a/newbs.md b/newbs.md new file mode 100644 index 00000000000..02b0a070f57 --- /dev/null +++ b/newbs.md @@ -0,0 +1,30 @@ +# The QMK Tutorial + +Your computer keyboard has a processor inside of it, similar to the one inside your computer. This processor runs software that is responsible for detecting button presses and informing the computer when keys are pressed. QMK Firmware fills the role of that software, detecting button presses and passing that information on to the host computer. When you build your custom keymap, you are creating an executable program for your keyboard. + +QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful keymaps — you only have to follow a few simple syntax rules. + +Not sure if your keyboard can run QMK? If it's a mechanical keyboard you built yourself chances are good it can. We support a [large number of hobbyist boards](http://qmk.fm/keyboards/). If your current keyboard can't run QMK there are a lot of choices out there for boards that do. + +## Is This Guide For Me? + +This guide is suitable for everyone who wants to build a keyboard firmware using the source code. If you are already a programmer you will find the process very familiar and easier to follow. If the thought of programming intimidates you please [take a look at our online GUI](newbs_building_firmware_configurator.md) instead. + +## Overview + +There are 4 main sections to this guide: + +1. [Setup Your Environment](newbs_getting_started.md) +2. [Building Your First Firmware](newbs_building_firmware.md) +3. [Flashing Firmware](newbs_flashing.md) +4. [Testing and Debugging](newbs_testing_debugging.md) + +This guide is focused on helping someone who has never compiled software before. It makes choices and recommendations based on that viewpoint. There are alternative methods for many of these procedures, and we support most of those alternatives. If you have any doubt about how to accomplish a task you can [ask us for guidance](getting_started_getting_help.md). + +## Additional Resources + +Beyond this guide there are several resources you may find helpful while you learn QMK. We've collected them on the [Learning Resources](newbs_learn_more_resources.md) page. + +## Open Source + +QMK is Open Source Software released under the GNU General Public License. diff --git a/newbs_building_firmware.md b/newbs_building_firmware.md new file mode 100644 index 00000000000..ed94a1460dc --- /dev/null +++ b/newbs_building_firmware.md @@ -0,0 +1,64 @@ +# Building Your First Firmware + +Now that you have setup your build environment you are ready to start building custom firmware. For this section of the guide we will bounce between 3 programs- your file manager, your text editor, and your terminal window. Keep all 3 open until you are done and happy with your keyboard firmware. + +## Create a New Keymap + +To create your own keymap you'll want to create a copy of the `default` keymap. If you configured your build environment in the last step you can do that easily with the QMK CLI: + + qmk new-keymap + +If you did not configure your environment, or you have multiple keyboards, you can specify a keyboard name: + + qmk new-keymap -kb + +Look at the output from that command, you should see something like this: + + Ψ keymap directory created in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/ + +This is the location of your new `keymap.c` file. + +## Open `keymap.c` In Your Favorite Text Editor + +Open your `keymap.c` file in your text editor. Inside this file you'll find the structure that controls how your keyboard behaves. At the top of `keymap.c` there may be some defines and enums that make the keymap easier to read. Farther down you'll find a line that looks like this: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +This line indicates where the list of Layers begins. Below that you'll find lines containing `LAYOUT`, and these lines indicate the start of a layer. Below that line is the list of keys that comprise a particular layer. + +!> When editing your keymap file be careful not to add or remove any commas. If you do you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is. + +## Customize The Layout To Your Liking + +How to complete this step is entirely up to you. Make the one change that's been bugging you, or completely rework everything. You can remove layers if you don't need all of them, or add layers up to a total of 32. There are a lot of features in QMK, explore the sidebar to the left under "Using QMK" to see the full list. To get you started here are a few of the easier to use features: + +* [Basic Keycodes](keycodes_basic.md) +* [Quantum Keycodes](quantum_keycodes.md) +* [Grave/Escape](feature_grave_esc.md) +* [Mouse keys](feature_mouse_keys.md) + +?> While you get a feel for how keymaps work, keep each change small. Bigger changes make it harder to debug any problems that arise. + +## Build Your Firmware :id=build-your-firmware + +When your changes to the keymap are complete you will need to build the firmware. To do so go back to your terminal window and run the compile command: + + qmk compile + +If you did not configure your environment, or you have multiple keyboards, you can specify a keyboard and/or keymap: + + qmk compile -kb -km + +While this compiles you will have a lot of output going to the screen informing you of what files are being compiled. It should end with output that looks similar to this: + +``` +Linking: .build/planck_rev5_default.elf [OK] +Creating load file for flashing: .build/planck_rev5_default.hex [OK] +Copying planck_rev5_default.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_default.hex [OK] + * The firmware size is fine - 27312/28672 (95%, 1360 bytes free) +``` + +## Flash Your Firmware + +Move on to [Flashing Firmware](newbs_flashing.md) to learn how to write your new firmware to your keyboard. diff --git a/newbs_building_firmware_configurator.md b/newbs_building_firmware_configurator.md new file mode 100644 index 00000000000..ac702f391bf --- /dev/null +++ b/newbs_building_firmware_configurator.md @@ -0,0 +1,13 @@ +# QMK Configurator + +[![QMK Configurator Screenshot](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/) + +The [QMK Configurator](https://config.qmk.fm) is an online graphical user interface that generates QMK Firmware hex files. + +Watch the [Video Tutorial](https://www.youtube.com/watch?v=-imgglzDMdY). Many people find that is enough information to start programming their own keyboard. + +The QMK Configurator works best with Chrome or Firefox. + +!> **Note: Files from other tools such as Keyboard Layout Editor (KLE), or kbfirmware will not be compatible with QMK Configurator. Do not load them, do not import them. QMK Configurator is a DIFFERENT tool.** + +Please refer to [QMK Configurator: Step by Step](configurator_step_by_step.md). diff --git a/newbs_flashing.md b/newbs_flashing.md new file mode 100644 index 00000000000..04c7c55aed9 --- /dev/null +++ b/newbs_flashing.md @@ -0,0 +1,111 @@ +# Flashing Your Keyboard + +Now that you've built a custom firmware file you'll want to flash your keyboard. + +## Put Your Keyboard into DFU (Bootloader) Mode + +In order to flash your custom firmware you must first put your keyboard into a special flashing mode. While it is in this mode you will not be able to type or otherwise use your keyboard. It is very important that you do not unplug the keyboard or otherwise interrupt the flashing process while the firmware is being written. + +Different keyboards have different ways to enter this special mode. If your PCB currently runs QMK, TMK, or PS2AVRGB (Bootmapper Client) and you have not been given specific instructions, try the following, in order: + +* Hold down both shift keys and press `Pause` +* Hold down both shift keys and press `B` +* Unplug your keyboard, hold down the Spacebar and `B` at the same time, plug in your keyboard and wait a second before releasing the keys +* Unplug your keyboard, hold down the top or bottom left key (usually Escape or Left Control) and plug in your keyboard +* Press the physical `RESET` button, usually located on the underside of the PCB +* Locate header pins on the PCB labeled `RESET` and `GND`, and short them together while plugging your PCB in + +If you've attempted all of the above to no avail, and the main chip on the board says `STM32` on it, this may be a bit more complicated. Generally your best bet is to ask on [Discord](https://discord.gg/Uq7gcHh) for assistance. It's likely some photos of the board will be asked for -- if you can get them ready beforehand it'll help move things along! + +Otherwise, you should see a message in yellow, similar to this in QMK Toolbox: + +``` +*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) +``` + +and this bootloader device will also be present in Device Manager, System Information.app, or `lsusb`. + +## Flashing Your Keyboard with QMK Toolbox + +The simplest way to flash your keyboard will be with the [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases). + +However, the Toolbox is currently only available for Windows and macOS. If you're using Linux (or just wish to flash the firmware from the command line), skip to the [Flash your Keyboard from the Command Line](#flash-your-keyboard-from-the-command-line) section. + +### Load the File into QMK Toolbox + +Begin by opening the QMK Toolbox application. You'll want to locate the firmware file in Finder or Explorer. Your keyboard firmware may be in one of two formats- `.hex` or `.bin`. QMK tries to copy the appropriate one for your keyboard into the root `qmk_firmware` directory. + +If you are on Windows or macOS, there are commands you can use to easily open the current folder in Explorer or Finder. + +#### Windows + +``` +start . +``` + +#### macOS + +``` +open . +``` + +The firmware file always follows this naming format: + +``` +_.{bin,hex} +``` + +For example, the `planck/rev5` with a `default` keymap will have this filename: + +``` +planck_rev5_default.hex +``` + +Once you have located your firmware file drag it into the "Local file" box in QMK Toolbox, or click "Open" and navigate to where your firmware file is stored. + +### Flash Your Keyboard + +Click the `Flash` button in QMK Toolbox. You will see output similar to the following: + +``` +*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) +*** Attempting to flash, please don't remove device +>>> dfu-programmer.exe atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer.exe atmega32u4 flash "D:\Git\qmk_firmware\gh60_satan_default.hex" + Checking memory from 0x0 to 0x3F7F... Empty. + 0% 100% Programming 0x3F80 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x3F80 bytes written into 0x7000 bytes memory (56.70%). +>>> dfu-programmer.exe atmega32u4 reset + +*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000) +``` + +## Flash your Keyboard from the Command Line + +This has been made pretty simple compared to what it used to be. When you are ready to compile and flash your firmware, open up your terminal window and run the flash command: + + qmk flash + +If you have not configured your keyboard/keymap name in the CLI, or you have multiple keyboards, you can specify the keyboard and keymap: + + qmk flash -kb -km + +This will check the keyboard's configuration, and then attempt to flash it based on the specified bootloader. This means that you don't need to know which bootloader that your keyboard uses. Just run the command, and let the command do the heavy lifting. + +However, this does rely on the bootloader being set by the keyboard. If this information is not configured, or you're using a board that doesn't have a supported target to flash it, you will see this error: + + WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. + +In this case, you'll have to fall back on specifying the bootloader. See the [Flashing Firmware](flashing.md) Guide for more details. + +## Test It Out! + +Congrats! Your custom firmware has been programmed to your keyboard! + +Give it a try and make sure everything works the way you want it to. We've written [Testing and Debugging](newbs_testing_debugging.md) to round out this guide, so head over there to learn about validating your firmware and how to troubleshoot your custom functionality. diff --git a/newbs_getting_started.md b/newbs_getting_started.md new file mode 100644 index 00000000000..dfb2d54fc4f --- /dev/null +++ b/newbs_getting_started.md @@ -0,0 +1,143 @@ +# Setting Up Your QMK Environment + +Before you can build keymaps, you need to install some software and set up your build environment. This only has to be done once no matter how many keyboards you plan to compile firmware for. + +## 1. Download Software + +There are a few pieces of software you'll need to get started. + +### Text Editor + +You'll need a program that can edit and save **plain text** files. If you're on Windows you can make do with Notepad, and on Linux you can use gedit. Both of these are simple but functional text editors. On macOS, be careful with the default TextEdit app: it will not save plain text files unless you explicitly select _Make Plain Text_ from the _Format_ menu. + +You can also download and install a dedicated text editor like [Sublime Text](https://www.sublimetext.com/) or [VS Code](https://code.visualstudio.com/). This is probably the best way to go regardless of platform, as these programs are specifically made for editing code. + +?> Not sure which text editor to use? Laurence Bradford wrote [a great introduction](https://learntocodewith.me/programming/basics/text-editors/) to the subject. + +### QMK Toolbox + +QMK Toolbox is an optional graphical program for Windows and macOS that allows you to both program and debug your custom keyboard. You will likely find it invaluable for easily flashing your keyboard and viewing debug messages that it prints. + +[Download the latest release here.](https://github.com/qmk/qmk_toolbox/releases/latest) + +* For Windows: `qmk_toolbox.exe` (portable) or `qmk_toolbox_install.exe` (installer) +* For macOS: `QMK.Toolbox.app.zip` (portable) or `QMK.Toolbox.pkg` (installer) + +### A Unix-like Environment + +Linux and macOS come with unix shells you can execute already. You will only need to setup your build environment. + +On Windows you will need to install MSYS2 or WSL and use those environments. Instructions for setting up MSYS2 are provided below. + +## 2. Prepare Your Build Environment :id=set-up-your-environment + +We've tried to make QMK as easy to set up as possible. You only have to prepare your Linux or Unix environment, then let QMK install the rest. + +?> If you haven't worked with the Linux/Unix command line before, there are a few basic concepts and commands you should learn. These resources will teach you enough to be able to work with QMK:
+[Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
+[Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +You will need to install MSYS2, Git, and the QMK CLI. + +Follow the installation instructions on the [MSYS2 homepage](http://www.msys2.org). Close any open MSYS terminals and open a new MinGW 64-bit terminal. **NOTE: This is *not* the same as the MSYS terminal that opens when installation is completed.** + +Then, run the following: + + pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip + python3 -m pip install qmk + +### macOS + +You will need to install Homebrew. Follow the instructions on the [Homebrew homepage](https://brew.sh). + +After Homebrew is installed run this command: + + brew install qmk/qmk/qmk + +### Linux + +You will need to install Git and Python. It's very likely that you already have both, but if not, one of the following commands should install them: + +* Debian / Ubuntu / Devuan: `sudo apt install git python3 python3-pip` +* Fedora / Red Hat / CentOS: `sudo yum install git python3 python3-pip` +* Arch / Manjaro: `sudo pacman -S git python python-pip python-setuptools libffi` + +Install the global CLI to bootstrap your system: + +`python3 -m pip install --user qmk` (on Arch-based distros you can also try the `qmk` package from AUR (**note**: it's maintained by a community member): `yay -S qmk`) + +### FreeBSD + +You will need to install Git and Python. It's possible that you already have both, but if not, run the following commands to install them: + + pkg install git python3 + +Make sure that `$HOME/.local/bin` is added to your `$PATH` so that locally install Python packages are available. + +Once installed, you can install QMK CLI: + + python3 -m pip install --user qmk + +## 3. Run QMK Setup :id=set-up-qmk + +After installing QMK you can set it up with this command: + + qmk setup + +In most situations you will want to answer Yes to all of the prompts. + +?>**Note on Debian, Ubuntu and their derivatives**: +It's possible, that you will get an error saying something like: `bash: qmk: command not found`. +This is due to a [bug](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155) Debian introduced with their Bash 4.4 release, which removed `$HOME/.local/bin` from the PATH. This bug was later fixed on Debian and Ubuntu. +Sadly, Ubuntu reitroduced this bug and is [yet to fix it](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562). +Luckily, the fix is easy. Run this as your user: `echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc` + +?>**Note on FreeBSD**: +It is suggested to run `qmk setup` as a non-`root` user to start with, but this will likely identify packages that need to be installed to your +base system using `pkg`. However the installation will probably fail when run as an unprivileged user. +To manually install the base dependencies, run `./util/qmk_install.sh` either as `root`, or with `sudo`. +Once that completes, re-run `qmk setup` to complete the setup and checks. + +?> If you already know [how to use GitHub](getting_started_github.md), we recommend that you create your own fork and use `qmk setup /qmk_firmware` to clone your personal fork. If you don't know what that means you can safely ignore this message. + +## 4. Test Your Build Environment + +Now that your QMK build environment is set up, you can build a firmware for your keyboard. Start by trying to build the keyboard's default keymap. You should be able to do that with a command in this format: + + qmk compile -kb -km default + +For example, to build a firmware for a Clueboard 66% you would use: + + qmk compile -kb clueboard/66/rev3 -km default + +When it is done you should have a lot of output that ends similar to this: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +## 5. Configure Your Build Environment (Optional) + +You can configure your build environment to set the defaults and make working with QMK less tedious. Let's do that now! + +Most people new to QMK only have 1 keyboard. You can set this keyboard as your default with the `qmk config` command. For example, to set your default keyboard to `clueboard/66/rev4`: + + qmk config user.keyboard=clueboard/66/rev4 + +You can also set your default keymap name. Most people use their GitHub username here, and we recommend that you do too. + + qmk config user.keymap= + +After this you can leave those arguments off and compile your keyboard like this: + + qmk compile + +# Creating Your Keymap + +You are now ready to create your own personal keymap! Move on to [Building Your First Firmware](newbs_building_firmware.md) for that. diff --git a/newbs_git_best_practices.md b/newbs_git_best_practices.md new file mode 100644 index 00000000000..c0cb3a29449 --- /dev/null +++ b/newbs_git_best_practices.md @@ -0,0 +1,16 @@ +# Best Git Practices for Working with QMK + +## Or, "How I Learned to Stop Worrying and Love Git." + +This section aims to instruct novices in the best ways to have a smooth experience in contributing to QMK. We will walk through the process of contributing to QMK, detailing some ways to make this task easier, and then later we'll break some things in order to teach you how to fix them. + +This section assumes a few things: + +1. You have a GitHub account, and have [forked the qmk_firmware repository](getting_started_github.md) to your account. +2. You've set up both [your build environment](newbs_getting_started.md#set-up-your-environment) and [QMK](newbs_getting_started.md#set-up-qmk). + +--- + +- Part 1: [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md) +- Part 2: [Resolving Merge Conflicts](newbs_git_resolving_merge_conflicts.md) +- Part 3: [Resynchronizing an Out-of-Sync Git Branch](newbs_git_resynchronize_a_branch.md) diff --git a/newbs_git_resolving_merge_conflicts.md b/newbs_git_resolving_merge_conflicts.md new file mode 100644 index 00000000000..467c13abba9 --- /dev/null +++ b/newbs_git_resolving_merge_conflicts.md @@ -0,0 +1,79 @@ +# Resolving Merge Conflicts + +Sometimes when your work in a branch takes a long time to complete, changes that have been made by others conflict with changes you have made to your branch when you open a pull request. This is called a *merge conflict*, and is what happens when multiple people edit the same parts of the same files. + +?> This document builds upon the concepts detailed in [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md). If you are not familiar with that document, please read it first, then return here. + +## Rebasing Your Changes + +A *rebase* is Git's way of taking changes that were applied at one point in the commit history, reversing them, and then applying the same changes at another point. In the case of a merge conflict, you can rebase your branch to grab the changes that were made between when you created your branch and the present time. + +To start, run the following: + +``` +git fetch upstream +git rev-list --left-right --count HEAD...upstream/master +``` + +The `git rev-list` command entered here returns the number of commits that differ between the current branch and QMK's master branch. We run `git fetch` first to make sure we have the refs that represent the current state of the upstream repo. The output of the `git rev-list` command entered returns two numbers: + +``` +$ git rev-list --left-right --count HEAD...upstream/master +7 35 +``` + +The first number represents the number of commits on the current branch since it was created, and the second number is the number of commits made to `upstream/master` since the current branch was created, and thus, the changes that are not recorded in the current branch. + +Now that the current states of both the current branch and the upstream repo are known, we can start a rebase operation: + +``` +git rebase upstream/master +``` + +This tells Git to undo the commits on the current branch, and then reapply them against QMK's master branch. + +``` +$ git rebase upstream/master +First, rewinding head to replay your work on top of it... +Applying: Commit #1 +Using index info to reconstruct a base tree... +M conflicting_file_1.txt +Falling back to patching base and 3-way merge... +Auto-merging conflicting_file_1.txt +CONFLICT (content): Merge conflict in conflicting_file_1.txt +error: Failed to merge in the changes. +hint: Use 'git am --show-current-patch' to see the failed patch +Patch failed at 0001 Commit #1 + +Resolve all conflicts manually, mark them as resolved with +"git add/rm ", then run "git rebase --continue". +You can instead skip this commit: run "git rebase --skip". +To abort and get back to the state before "git rebase", run "git rebase --abort". +``` + +This tells us that we have a merge conflict, and gives the name of the file with the conflict. Open the conflicting file in your text editor, and somewhere in the file, you'll find something like this: + +``` +<<<<<<< HEAD +

For help with any issues, email us at support@webhost.us.

+======= +

Need help? Email support@webhost.us.

+>>>>>>> Commit #1 +``` + +The line `<<<<<<< HEAD` marks the beginning of a merge conflict, and the `>>>>>>> Commit #1` line marks the end, with the conflicting sections separated by `=======`. The part on the `HEAD` side is from the QMK master version of the file, and the part marked with the commit message is from the current branch and commit. + +Because Git tracks *changes to files* rather than the contents of the files directly, if Git can't find the text that was in the file previous to the commit that was made, it won't know how to edit the file. Re-editing the file will solve the conflict. Make your changes, and then save the file. + +``` +

Need help? Email support@webhost.us.

+``` + +Now run: + +``` +git add conflicting_file_1.txt +git rebase --continue +``` + +Git logs the changes to the conflicting file, and continues applying the commits from our branch until it reaches the end. diff --git a/newbs_git_resynchronize_a_branch.md b/newbs_git_resynchronize_a_branch.md new file mode 100644 index 00000000000..3e7acdba7ad --- /dev/null +++ b/newbs_git_resynchronize_a_branch.md @@ -0,0 +1,71 @@ +# Resynchronizing an Out-of-Sync Git Branch + +Suppose you have committed to your `master` branch, and now need to update your QMK repository. You could `git pull` QMK's `master` branch into your own, but GitHub will tell you that your branch is a number of commits ahead of `qmk:master`, which can create issues if you want to make a pull request to QMK. + +?> This document builds upon the concepts detailed in [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md). If you are not familiar with that document, please read it first, then return here. + +## Backing Up the Changes on Your Own Master Branch (Optional) + +No one wants to lose work if it can be helped. If you want to save the changes you've already made to your `master` branch, the simplest way to do so is to simply create a duplicate of your "dirty" `master` branch: + +```sh +git branch old_master master +``` + +Now you have a branch named `old_master` that is a duplicate of your `master` branch. + +## Resynchronizing Your Branch + +Now it's time to resynchronize your `master` branch. For this step, you'll want to have QMK's repository configured as a remote in Git. To check your configured remotes, run `git remote -v`, which should return something similar to: + +```sh +QMKuser ~/qmk_firmware (master) +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +If you only see one fork referenced: + +```sh +QMKuser ~/qmk_firmware (master) +$ git remote -v +origin https://github.com/qmk/qmk_firmware.git (fetch) +origin https://github.com/qmk/qmk_firmware.git (push) +``` + +add a new remote with: + +```sh +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +Then, redirect the `origin` remote to your own fork with: + +```sh +git remote set-url origin https://github.com//qmk_firmware.git +``` + +Now that you have both remotes configured, you need to update the references for the upstream repository, which is QMK's, by running: + +```sh +git fetch upstream +``` + +At this point, resynchronize your branch to QMK's by running: + +```sh +git reset --hard upstream/master +``` + +These steps will update the repository on your computer, but your GitHub fork will still be out of sync. To resynchronize your fork on GitHub, you need to push to your fork, instructing Git to override any remote changes that are not reflected in your local repository. To do this, run: + +```sh +git push --force-with-lease +``` + +!> **DO NOT** run `git push --force-with-lease` on a fork to which other users post commits. This will erase their commits. + +Now your GitHub fork, your local files, and QMK's repository are all the same. From here you can make further needed changes ([use a branch!](newbs_git_using_your_master_branch.md#making-changes)) and post them as normal. diff --git a/newbs_git_using_your_master_branch.md b/newbs_git_using_your_master_branch.md new file mode 100644 index 00000000000..c27323f5515 --- /dev/null +++ b/newbs_git_using_your_master_branch.md @@ -0,0 +1,74 @@ +# Your Fork's Master: Update Often, Commit Never + +It is highly recommended for QMK development, regardless of what is being done or where, to keep your `master` branch updated, but ***never*** commit to it. Instead, do all your changes in a development branch and issue pull requests from your branches when you're developing. + +To reduce the chances of merge conflicts — instances where two or more users have edited the same part of a file concurrently — keep your `master` branch relatively up-to-date, and start any new developments by creating a new branch. + +## Updating your master branch + +To keep your `master` branch updated, it is recommended to add the QMK Firmware repository ("repo") as a remote repository in git. To do this, open your Git command line interface and enter: + +``` +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +?> The name `upstream` is arbitrary, but a common convention; you can give the QMK remote any name that suits you. Git's `remote` command uses the syntax `git remote add `, `` being shorthand for the remote repo. This name can be used with many Git commands, including but not limited to `fetch`, `pull` and `push`, to specify the remote repo on which to act. + +To verify that the repository has been added, run `git remote -v`, which should return the following: + +``` +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +Now that this is done, you can check for updates to the repo by running `git fetch upstream`. This retrieves the branches and tags — collectively referred to as "refs" — from the QMK repo, which now has the nickname `upstream`. We can now compare the data on our fork `origin` to that held by QMK. + +To update your fork's master, run the following, hitting the Enter key after each line: + +``` +git checkout master +git fetch upstream +git pull upstream master +git push origin master +``` + +This switches you to your `master` branch, retrieves the refs from the QMK repo, downloads the current QMK `master` branch to your computer, and then uploads it to your fork. + +## Making Changes :id=making-changes + +To make changes, create a new branch by entering: + +``` +git checkout -b dev_branch +git push --set-upstream origin dev_branch +``` + +This creates a new branch named `dev_branch`, checks it out, and then saves the new branch to your fork. The `--set-upstream` argument tells git to use your fork and the `dev_branch` branch every time you use `git push` or `git pull` from this branch. It only needs to be used on the first push; after that, you can safely use `git push` or `git pull`, without the rest of the arguments. + +?> With `git push`, you can use `-u` in place of `--set-upstream` — `-u` is an alias for `--set-upstream`. + +You can name your branch nearly anything you want, though it is recommended to name it something related to the changes you are going to make. + +By default `git checkout -b` will base your new branch on the branch that is currently checked out. You can base your new branch on an existing branch that is not checked out by adding the name of the existing branch to the command: + +``` +git checkout -b dev_branch master +``` + +Now that you have a development branch, open your text editor and make whatever changes you need to make. It is recommended to make many small commits to your branch; that way, any change that causes issues can be more easily traced and undone if needed. To make your changes, edit and save any files that need to be updated, add them to Git's *staging area*, and then commit them to your branch: + +``` +git add path/to/updated_file +git commit -m "My commit message." +``` + +`git add` adds files that have been changed to Git's *staging area*, which is Git's "loading zone." This contains the changes that are going to be *committed* by `git commit`, which saves the changes to the repo. Use descriptive commit messages so you can know what was changed at a glance. + +?> If you've changed multiple files, you can use `git add -- path/to/file1 path/to/file2 ...` to add all your desired files. + +## Publishing Your Changes + +The last step is to push your changes to your fork. To do this, enter `git push`. Git will then publish the current state of `dev_branch` to your fork. diff --git a/newbs_learn_more_resources.md b/newbs_learn_more_resources.md new file mode 100644 index 00000000000..8f1ddec1e25 --- /dev/null +++ b/newbs_learn_more_resources.md @@ -0,0 +1,17 @@ +# Learning Resources + +These resources are aimed at giving new members in the QMK community more understanding to the information provided in the Newbs docs. + +**QMK resources**: + +* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – A user-created blog covering the basics of how to use QMK Firmware, as seen from a new user's perspective. + +**Command Line resources**: + +* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line) + +**Git resources**: + +* [Great General Tutorial](https://www.codecademy.com/learn/learn-git) +* [Flight Rules For Git](https://github.com/k88hudson/git-flight-rules) +* [Git Game To Learn From Examples](https://learngitbranching.js.org/) diff --git a/newbs_testing_debugging.md b/newbs_testing_debugging.md new file mode 100644 index 00000000000..1812389020f --- /dev/null +++ b/newbs_testing_debugging.md @@ -0,0 +1,94 @@ +# Testing and Debugging + +Once you've flashed your keyboard with a custom firmware you're ready to test it out. With a little bit of luck everything will work perfectly, but if not this document will help you figure out what's wrong. + +## Testing + +Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK. + +## Debugging :id=debugging + +Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DEBUG` keycode in your keymap, use the [Command](feature_command.md) feature to enable debug mode, or add the following code to your keymap. + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + +## Debugging Tools + +There are two different tools you can use to debug your keyboard. + +### Debugging With QMK Toolbox + +For compatible platforms, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) can be used to display debug messages from your keyboard. + +### Debugging With hid_listen + +Prefer a terminal based solution? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provided by PJRC, can also be used to display debug messages. Prebuilt binaries for Windows,Linux,and MacOS are available. + +## Sending Your Own Debug Messages + +Sometimes it's useful to print debug messages from within your [custom code](custom_quantum_functions.md). Doing so is pretty simple. Start by including `print.h` at the top of your file: + + #include + +After that you can use a few different print functions: + +* `print("string")`: Print a simple string. +* `uprintf("%s string", var)`: Print a formatted string +* `dprint("string")` Print a simple string, but only when debug mode is enabled +* `dprintf("%s string", var)`: Print a formatted string, but only when debug mode is enabled + +## Debug Examples + +Below is a collection of real world debugging examples. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md). + +### Which matrix position is this keypress? + +When porting, or when attempting to diagnose pcb issues, it can be useful to know if a keypress is scanned correctly. To enable logging for this scenario, add the following code to your keymaps `keymap.c` + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + // If console is enabled, it will print the matrix position and status of each key pressed +#ifdef CONSOLE_ENABLE + uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); +#endif + return true; +} +``` + +Example output +```text +Waiting for device:....... +Listening: +KL: kc: 169, col: 0, row: 0, pressed: 1 +KL: kc: 169, col: 0, row: 0, pressed: 0 +KL: kc: 174, col: 1, row: 0, pressed: 1 +KL: kc: 174, col: 1, row: 0, pressed: 0 +KL: kc: 172, col: 2, row: 0, pressed: 1 +KL: kc: 172, col: 2, row: 0, pressed: 0 +``` + +### How long did it take to scan for a keypress? + +When testing performance issues, it can be useful to know the frequency at which the switch matrix is being scanned. To enable logging for this scenario, add the following code to your keymaps `config.h` + +```c +#define DEBUG_MATRIX_SCAN_RATE +``` + +Example output +```text + > matrix scan frequency: 315 + > matrix scan frequency: 313 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 + > matrix scan frequency: 316 +``` diff --git a/one_shot_keys.md b/one_shot_keys.md new file mode 100644 index 00000000000..aa3db5acb21 --- /dev/null +++ b/one_shot_keys.md @@ -0,0 +1,102 @@ +# One Shot Keys + +One shot keys are keys that remain active until the next key is pressed, and then are released. This allows you to type keyboard combinations without pressing more than one key at a time. These keys are usually called "Sticky keys" or "Dead keys". + +For example, if you define a key as `OSM(MOD_LSFT)`, you can type a capital A character by first pressing and releasing shift, and then pressing and releasing A. Your computer will see the shift key being held the moment shift is pressed, and it will see the shift key being released immediately after A is released. + +One shot keys also work as normal modifiers. If you hold down a one shot key and type other keys, your one shot will be released immediately after you let go of the key. + +Additionally, hitting keys five times in a short period will lock that key. This applies for both One Shot Modifiers and One Shot Layers, and is controlled by the `ONESHOT_TAP_TOGGLE` define. + +You can control the behavior of one shot keys by defining these in `config.h`: + +```c +#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */ +#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */ +``` + +* `OSM(mod)` - Momentarily hold down *mod*. You must use the `MOD_*` keycodes as shown in [Mod Tap](mod_tap.md), not the `KC_*` codes. +* `OSL(layer)` - momentary switch to *layer*. + +Sometimes, you want to activate a one-shot key as part of a macro or tap dance routine. + +For one shot layers, you need to call `set_oneshot_layer(LAYER, ONESHOT_START)` on key down, and `clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED)` on key up. If you want to cancel the oneshot, call `reset_oneshot_layer()`. + +For one shot mods, you need to call `set_oneshot_mods(MOD)` to set it, or `clear_oneshot_mods()` to cancel it. + +!> If you're having issues with OSM translating over Remote Desktop Connection, this can be fixed by opening the settings, going to the "Local Resources" tap, and in the keyboard section, change the drop down to "On this Computer". This will fix the issue and allow OSM to function properly over Remote Desktop. + +## Callbacks + +When you'd like to perform custom logic when pressing a one shot key, there are several callbacks you can choose to implement. You could indicate changes in one shot keys by flashing an LED or making a sound, for example. + +There is a callback for `OSM(mod)`. It is called whenever the state of any one shot modifier key is changed: when it toggles on, but also when it is toggled off. You can use it like this: + +```c +void oneshot_mods_changed_user(uint8_t mods) { + if (mods & MOD_MASK_SHIFT) { + println("Oneshot mods SHIFT"); + } + if (mods & MOD_MASK_CTRL) { + println("Oneshot mods CTRL"); + } + if (mods & MOD_MASK_ALT) { + println("Oneshot mods ALT"); + } + if (mods & MOD_MASK_GUI) { + println("Oneshot mods GUI"); + } + if (!mods) { + println("Oneshot mods off"); + } +} +``` + +The `mods` argument contains the active mods after the change, so it reflects the current state. + +When you use One Shot Tap Toggle (by adding `#define ONESHOT_TAP_TOGGLE 2` in your `config.h` file), you may lock a modifier key by pressing it the specified amount of times. There's a callback for that, too: + +```c +void oneshot_locked_mods_changed_user(uint8_t mods) { + if (mods & MOD_MASK_SHIFT) { + println("Oneshot locked mods SHIFT"); + } + if (mods & MOD_MASK_CTRL) { + println("Oneshot locked mods CTRL"); + } + if (mods & MOD_MASK_ALT) { + println("Oneshot locked mods ALT"); + } + if (mods & MOD_MASK_GUI) { + println("Oneshot locked mods GUI"); + } + if (!mods) { + println("Oneshot locked mods off"); + } +} +``` + +Last, there is also a callback for the `OSL(layer)` one shot key: + +```c +void oneshot_layer_changed_user(uint8_t layer) { + if (layer == 1) { + println("Oneshot layer 1 on"); + } + if (!layer) { + println("Oneshot layer off"); + } +} +``` + +If any one shot layer is switched off, `layer` will be zero. When you're looking to do something on any layer change instead of one shot layer changes, `layer_state_set_user` is a better callback to use. + +If you are making your own keyboard, there are also `_kb` equivalent functions: + +```c +void oneshot_locked_mods_changed_kb(uint8_t mods); +void oneshot_mods_changed_kb(uint8_t mods); +void oneshot_layer_changed_kb(uint8_t layer); +``` + +As with any callback, be sure to call the `_user` variant to allow for further customizability. diff --git a/other_eclipse.md b/other_eclipse.md new file mode 100644 index 00000000000..b2655ca08dc --- /dev/null +++ b/other_eclipse.md @@ -0,0 +1,88 @@ +# Setting up Eclipse for QMK Development + +[Eclipse][1] is an open-source [Integrated Development Environment](https://en.wikipedia.org/wiki/Integrated_development_environment) (IDE) widely used for Java development, but with an extensible plugin system that allows to customize it for other languages and usages. + +Using an IDE such as Eclipse provides many advantages over a plain text editor, such as: +* intelligent code completion +* convenient navigation in the code +* refactoring tools +* build automation (no need for the command-line) +* a GUI for GIT +* static code analysis +* many other tools such as debugging, code formatting, showing call hierarchies etc. + +The purpose of the is page is to document how to set-up Eclipse for developing AVR software, and working on the QMK code base. + +Note that this set-up has been tested on Ubuntu 16.04 only for the moment. + +# Prerequisites +## Build Environment +Before starting, you must have followed the [Getting Started](newbs_getting_started.md) section of the Tutorial. In particular, you must have been able to build the firmware with [the `qmk compile` command](newbs_building_firmware.md#build-your-firmware). + +## Java +Eclipse is a Java application, so you will need to install Java 8 or more recent to be able to run it. You may choose between the JRE or the JDK, the latter being useful if you intend to do Java development. + +# Install Eclipse and Its Plugins +Eclipse comes in [several flavours](http://www.eclipse.org/downloads/eclipse-packages/) depending on the target usage that you will have. There is no package comprising the AVR stack, so we will need to start from Eclipse CDT (C/C++ Development Tooling) and install the necessary plugins. + +## Download and Install Eclipse CDT +If you already have Eclipse CDT on your system, you can skip this step. However it is advised to keep it up-to-date for better support. + +If you have another Eclipse package installed, it is normally possible to [install the CDT plugin over it](https://eclipse.org/cdt/downloads.php). However it is probably better to reinstall it from scratch to keep it light and avoid the clutter of tools that you don't need for the projects you will be working on. + +Installation is very simple: follow the [5 Steps to Install Eclipse](https://eclipse.org/downloads/eclipse-packages/?show_instructions=TRUE), and choose **Eclipse IDE for C/C++ Developers** at Step 3. + +Alternatively, you can also directly [download Eclipse IDE for C/C++ Developers](http://www.eclipse.org/downloads/eclipse-packages/) ([direct link to current version](http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr)) and extract the package to the location of your choice (this creates an `eclipse` folder). + +## First Launch +When installation is complete, click the Launch button. (If you extracted the package manually, open the Eclipse installation folder and double-click the `eclipse` executable) + +When you are prompted with the Workspace Selector, select a directory that will hold Eclipse metadata and usually your projects. **Do not select the `qmk_firmware` directory**, this will be the project directory. Select the parent folder instead, or another (preferably empty) folder of your choice (the default is fine if you do not use it yet). + +Once started, click the Workbench button at the top right to switch to the workbench view (there is a also checkbox at the bottom to skip the welcome screen at startup). + +## Install the Necessary Plugins +Note: you do not need to restart Eclipse after installing each plugin. Simply restart once all plugins are installed. + +### [The AVR Plugin](http://avr-eclipse.sourceforge.net/) +This is the most important plugin as it will allow Eclipse to _understand_ AVR C code. Follow [the instructions for using the update site](http://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download#Update_Site), and agree with the security warning for unsigned content. + +### [ANSI Escape in Console](https://marketplace.eclipse.org/content/ansi-escape-console) +This plugin is necessary to properly display the colored build output generated by the QMK makefile. + +1. Open Help > Eclipse Marketplace… +2. Search for _ANSI Escape in Console_ +3. Click the Install button of the plugin +4. Follow the instructions and agree again with the security warning for unsigned content. + +Once both plugins are installed, restart Eclipse as prompted. + +# Configure Eclipse for QMK +## Importing the Project +1. Click File > New > Makefile Project with Existing Code +2. On the next screen: + * Select the directory where you cloned the repository as _Existing Code Location_; + * (Optional) Give a different name to the project¹, e.g. _QMK_ or _Quantum_; + * Select the _AVR-GCC Toolchain_; + * Keep the rest as-is and click Finish + + ![Importing QMK in Eclipse](http://i.imgur.com/oHYR1yW.png) + +3. The project will now be loaded and indexed. Its files can be browsed easily through the _Project Explorer_ on the left. + +¹ There might be issues for importing the project with a custom name. If it does not work properly, try leaving the default project name (i.e. the name of the directory, probably `qmk_firmware`). + +## Build Your Keyboard +We will now configure a make target that cleans the project and builds the keymap of your choice. + +1. On the right side of the screen, select the Make Target tab +2. Expand the folder structure to the keyboard of your choice, e.g. `qmk_firmware/keyboards/ergodox` +3. Right-click on the keyboard folder and select New… (or select the folder and click the New Make Target icon above the tree) +4. Choose a name for your build target, e.g. _clean \_ +5. Make Target: this is the arguments that you give to `make` when building from the command line. If your target name does not match these arguments, uncheck Same as target name and input the correct arguments, e.g. `clean ` +6. Leave the other options checked and click OK. Your make target will now appear under the selected keyboard. +7. (Optional) Toggle the Hide Empty Folders icon button above the targets tree to only show your build target. +8. Double-click the build target you created to trigger a build. +9. Select the Console view at the bottom to view the running build. + + [1]: https://en.wikipedia.org/wiki/Eclipse_(software) diff --git a/other_vscode.md b/other_vscode.md new file mode 100644 index 00000000000..823f8b49821 --- /dev/null +++ b/other_vscode.md @@ -0,0 +1,117 @@ +# Setting up Visual Studio Code for QMK Development + +[Visual Studio Code](https://code.visualstudio.com/) (VS Code) is an open-source code editor that supports many different programming languages. + +Using a full-featured editor such as VS Code provides many advantages over a plain text editor, such as: +* intelligent code completion +* convenient navigation in the code +* refactoring tools +* build automation (no need for the command-line) +* a graphical front end for GIT +* many other tools such as debugging, code formatting, showing call hierarchies etc. + +The purpose of this page is to document how to set up VS Code for developing QMK Firmware. + +This guide covers how to configure everything needed on Windows and Ubuntu 18.04 + +# Set up VS Code +Before starting, you will want to make sure that you have all of the build tools set up, and QMK Firmware cloned. Head to the the [Newbs Getting Started Guide](newbs_getting_started.md) to get things set up, if you haven't already. + +## Windows + +### Prerequisites + +* [Git for Windows](https://git-scm.com/download/win) (This link will prompt to save/run the installer) + + 1. Disable all of the options but `Git LFS (Large File Support)` and `Check daily for Git for Windows updates`. + 2. Set the default editor to `Use Visual Studio Code as Git's default editor` + 3. Select the `Use Git from Git Bash only` option, since that's the option that you should use here. + 4. For the `Choosing HTTPS transport backend`, either option should be fine. + 5. Select the `Checkout as-is, commit Unix-style line endings` option. QMK Firmware uses Unix style commits. + 6. For the extra options, leave the default options as is. + + This software is needed for Git support in VS Code. It may be possible to not include this, but it is much simpler to just use this. + +* [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases) (Optional) + + This software provides better support for Git by providing secure storage for git credentials, MFA and personal access token generation. + + This isn't strictly needed, but we would recommend it. + + +### Installing VS Code + +1. Head to [VS Code](https://code.visualstudio.com/) and download the installer +2. Run the installer + +This part is super simple. However, there is some configuration that we need to do to ensure things are configured correctly. + +### Configuring VS Code + +First, we need to set up IntelliSense. This isn't strictly required, but it will make your life a LOT easier. To do this, we need to create the `.vscode/c_cpp_properties.json` file in the QMK Firmware folder, You can do this all manually, but I've done most of the work already. + +Grab [this file](https://gist.github.com/drashna/48e2c49ce877be592a1650f91f8473e8) and save it. You may need to edit this file, if you didn't install MSYS2 to the default location, or are using WSL/LxSS. + +Once you have saved this file, you will need to reload VS Code, if it was already running. + +?> You should see an `extensions.json` and `settings.json` file in the `.vscode` folder, as well. + + +Now, we will set up the MSYS2 window to show up in VSCode as the integrated terminal. This has a number of advantages. Mostly, you can control+click on errors and jump to those files. This makes debugging much easier. It's also nice, in that you don't have to jump to another window. + +1. Click File > Preferences > > Settings +2. Click on the {} button, in the top right to open the `settings.json` file. +3. Set the file's content to: + + ```json + { + "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", + "terminal.integrated.env.windows": { + "MSYSTEM": "MINGW64", + "CHERE_INVOKING": "1" + }, + "terminal.integrated.shellArgs.windows": [ + "--login" + ], + "terminal.integrated.cursorStyle": "line" + } + ``` + + If there are settings here already, then just add everything between the first and last curly brackets and separate the existing settings with a comma from the newly added ones. + +?> If you installed MSYS2 to a different folder, then you'll need to change the path for `terminal.integrated.shell.windows` to the correct path for your system. + +4. Hit Ctrl-` (Grave) to bring up the terminal or go to View > Terminal (command `workbench.action.terminal.toggleTerminal`). A new terminal will be opened if there isn‘t one already. + + This should start the terminal in the workspace's folder (so the `qmk_firmware` folder), and then you can compile your keyboard. + + +## Every other Operating System + +1. Head to [VS Code](https://code.visualstudio.com/) and download the installer +2. Run the installer +3. That's it + +No, really, that's it. The paths needed are already included when installing the packages, and it is much better about detecting the current workspace files and parsing them for IntelliSense. + +## Plugins + +There are a number of extensions that you may want to install: + +* [Git Extension Pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack) - +This installs a bunch of Git related tools that may make using Git with QMK Firmware easier. +* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - _[Optional]_ - Helps to keep the code to the QMK Coding Conventions. +* [Bracket Pair Colorizer 2](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2) - _[Optional]_ - This color codes the brackets in your code, to make it easier to reference nested code. +* [GitHub Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview) - _[Optional]_ - Makes the markdown preview in VS Code more like GitHub's. +* [VS Live Share Extension Pack](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) - _[Optional]_ - This extension allows somebody else to access your workspace (or you to access somebody else's workspace) and help out. This is great if you're having issues and need some help from somebody. +* [VIM Keymap](https://marketplace.visualstudio.com/items?itemName=GiuseppeCesarano.vim-keymap) - _[Optional]_ - For those that prefer VIM style keybindings. There are other options for this, too. +* [Travis CI Status](https://marketplace.visualstudio.com/items?itemName=felixrieseberg.vsc-travis-ci-status) - _[Optional]_ - This shows the current Travis CI status, if you have it set up. + +Restart once you've installed any extensions + +# Configure VS Code for QMK +1. Click File > Open Folder +2. Open the QMK Firmware folder that you cloned from GitHub. +3. Click File > Save Workspace As... + +And now you're ready to code QMK Firmware in VS Code diff --git a/platformdev_chibios_earlyinit.md b/platformdev_chibios_earlyinit.md new file mode 100644 index 00000000000..5fd78bb3364 --- /dev/null +++ b/platformdev_chibios_earlyinit.md @@ -0,0 +1,64 @@ +# Arm/ChibiOS Early Initialization :id=chibios-early-init + +This page describes a part of QMK that is a somewhat advanced concept, and is only relevant to keyboard designers. + +QMK uses ChibiOS as the underlying layer to support a multitude of Arm-based devices. Each ChibiOS-supported keyboard has a low-level board definition which is responsible for initializing hardware peripherals such as the clocks, and GPIOs. + +Older QMK revisions required duplication of these board definitions inside your keyboard's directory in order to override such early initialization points; this is now abstracted into the following APIs, and allows usage of the board definitions supplied with ChibiOS itself. Check `/lib/chibios/os/hal/boards` for the list of official definitions. If your keyboard needs extra initialization at a very early stage, consider providing keyboard-level overrides of the following APIs instead of duplicating the board definitions: + +## `early_hardware_init_pre()` :id=early-hardware-init-pre + +The function `early_hardware_init_pre` is the earliest possible code that can be executed by a keyboard firmware. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the start of the function. + +This is executed before RAM gets cleared, and before clocks or GPIOs are configured; for example, ChibiOS delays are not likely to work at this point. After executing this function, RAM on the MCU may be zero'ed. Assigning values to variables during execution of this function may be overwritten. + +As such, if you wish to override this API consider limiting use to writing to low-level registers. The default implementation of this function can be configured to jump to bootloader if a `RESET` key was pressed: + +| `config.h` override | Description | Default | +|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP` | Whether or not bootloader is to be executed during the early initialisation code of QMK. | `FALSE` | +| `#define STM32_BOOTLOADER_ADDRESS` | Relevant for single-bank STM32 MCUs, signifies the memory address to jump to bootloader. Consult [AN2606](https://www.st.com/content/st_com/en/search.html#q=an2606-t=resources-page=1) for the _System Memory_ address for your MCU. This value should be of the format `0x11111111`. | `` | +| `#define STM32_BOOTLOADER_DUAL_BANK` | Relevant for dual-bank STM32 MCUs, signifies that a GPIO is to be toggled in order to enter bootloader mode. | `FALSE` | +| `#define STM32_BOOTLOADER_DUAL_BANK_GPIO` | Relevant for dual-bank STM32 MCUs, the pin to toggle when attempting to enter bootloader mode, e.g. `B8` | `` | +| `#define STM32_BOOTLOADER_DUAL_BANK_POLARITY` | Relevant for dual-bank STM32 MCUs, the value to set the pin to in order to trigger charging of the RC circuit. e.g. `0` or `1`. | `0` | +| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100000` | + +Kinetis MCUs have no configurable options. + +Alternatively, to implement your own version of this function, in your keyboard's source files: + +```c +void early_hardware_init_pre(void) { + // do things with registers +} +``` + +## `early_hardware_init_post()` :id=early-hardware-init-post + +The function `early_hardware_init_post` is the next earliest possible code that can be executed by a keyboard firmware. This is executed after RAM has been cleared, and clocks and GPIOs are configured. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the end of the function. + +Much like `early_hardware_init_pre`, ChibiOS has not yet been initialized either, so the same restrictions on delays and timing apply. + +If you wish to override this API, consider limiting functionality to register writes, variable initialization, and GPIO toggling. The default implementation of this function is to do nothing. + +To implement your own version of this function, in your keyboard's source files: + +```c +void early_hardware_init_post(void) { + // toggle GPIO pins and write to variables +} +``` + +## `board_init()` :id=board-init + +The function `board_init` is executed directly after the ChibiOS initialization routines have completed. At this stage, all normal low-level functionality should be available for use (including timers and delays), with the restriction that USB is not yet connected. This is intended as a replacement for the ChibiOS board definition's `boardInit` function. + +The default implementation of this function is to do nothing. + +To implement your own version of this function, in your keyboard's source files: + +```c +void board_init(void) { + // initialize anything that requires ChibiOS +} +``` \ No newline at end of file diff --git a/platformdev_selecting_arm_mcu.md b/platformdev_selecting_arm_mcu.md new file mode 100644 index 00000000000..c115aa6e0fd --- /dev/null +++ b/platformdev_selecting_arm_mcu.md @@ -0,0 +1,58 @@ +# Choosing an Arm MCU :id=choose-arm-mcu + +This page outlines the selection criteria to ensure compatibility with Arm/ChibiOS. + +QMK uses the Hardware Abstraction Layer of ChibiOS in order to run on Arm devices. ChibiOS in general is best supported on STM32 devices, both in the perspective of base MCU support, as well as on-MCU peripheral support. As an extension to the core ChibiOS MCU support, QMK also utilises ChibiOS-Contrib (which includes the Kinetis MCU support layer, as an example), but it does not provide as great a level of peripheral support or general testing for supported devices. + +Adding support for new MCU families must go through ChibiOS or ChibiOS-Contrib -- QMK does not have the bandwidth, resources, nor the inclination to maintain long-term MCU support for your board of choice. + +To be clear: this also includes commercial boards -- unless agreed upon by all parties, QMK will not take over maintenance of a bespoke MCU support package. Even if MCU support is upstreamed into ChibiOS/ChibiOS-Contrib, QMK reserves the right to deprecate and/or remove keyboards utilising support packages that aren't kept up to date with upstream ChibiOS itself. + +## Selecting an already-supported MCU :id=selecting-already-supported-mcu + +### STM32 families + +As outlined earlier, STM32 is the preferred option to ensure greatest compatibility with the subsystems already implemented in QMK. Not all subsystems are compatible yet, but for the most widely-used support is already present. + +The simplest solution to determine if an STM32 MCU is compatible is to navigate to the list of supported STM32 ports in QMK's [ChibiOS fork](https://github.com/qmk/ChibiOS/tree/master/os/hal/ports/STM32). Inside this directory, each of the supported STM32 families will be listed, and inside each family a file called `stm32_registry.h` will be present. Scanning through these files will show `#define`s such as the following, which can be used to determine if ChibiOS supports a particular MCU: + +```c +#if defined(STM32F303xC) || defined(__DOXYGEN__) +``` + +The example shows that STM32F303xC devices are supported by ChibiOS. + +The next step is to ensure that USB is supported on those devices by ChibiOS -- you can confirm this by checking inside the same section guarded by the `#define` above, specifically for the following to be `TRUE`: + +```c +#define STM32_HAS_USB TRUE +``` + +or one of the following being `TRUE`: + +```c +#define STM32_HAS_OTG1 TRUE +#define STM32_HAS_OTG2 TRUE +``` + +For the most part, this is the bare minimum to be able to have a high confidence that QMK will be able to run on your MCU. After that, it's all up to configuration. + +### Non-STM32 families + +ChibiOS does have support for a handful of non-STM32 devices, and the list can be found in QMK's [ChibiOS fork](https://github.com/qmk/ChibiOS/tree/master/os/hal/ports) and [ChibiOS-Contrib fork](https://github.com/qmk/ChibiOS-Contrib/tree/master/os/hal/ports). Non-STM32 support is likely out of date, and only supports ancient MCUs -- whilst it might be possible to use these, it's not recommended. + +Do note that there are sometimes licensing restrictions with respect to redistribution. As an example, binaries built for nRF5 are not able to be redistributed via QMK Configurator, due to the licensing of their board support package. + +## Adding support for a new STM32 MCU (for an existing family) :id=add-new-stm32-mcu + +Usually, one can "masquerade" as an existing MCU of the same family, especially if the only difference is RAM or Flash size. As an example, some MCUs within the same family are virtually identical, with the exception of adding a cryptographic peripheral -- STM32L072 vs. STM32L082 for instance. Given the unlikely use of the cryptographic peripheral, L082 chips can actually run as if they're an L072, and can be targeted accordingly. + +Adding proper support for new MCUs within an existing STM32 family should ideally be upstreamed to ChibiOS. In general, this will require modifications of the `stm32_registry.h` file, providing correct responses for the same `#define`s provided for the other MCUs in that family. + +## Adding support for a new STM32 Family :id=add-new-stm32-family + +If this is a requirement, this needs to go through upstream ChibiOS before QMK would consider accepting boards targeting the new family. More information for porting should be sought by approaching ChibiOS directly, rather than through QMK. + +## Adding support for a new MCU Family :id=add-new-mcu-family + +As stated earlier, in order for a new MCU family to be supported by QMK, it needs to be upstreamed into ChibiOS-Contrib before QMK will consider accepting boards using it. The same principle applies for development -- you're best approaching the ChibiOS-Contrib maintainers to get a bit more of an idea on what's involved with upstreaming your contribution. diff --git a/power.txt b/power.txt new file mode 100644 index 00000000000..ff28ba0c7f1 --- /dev/null +++ b/power.txt @@ -0,0 +1,62 @@ +Time to Sleep +============= +USB suspend no activity on USB line for 3ms +No Interaction no user interaction + matrix has no change + matrix has no switch on + + +AVR Power Management +==================== + +V-USB suspend + USB suspend + http://vusb.wikidot.com/examples + +MCUSR MCU Status Register + WDRF Watchdog Reset Flag + BORF + EXTRF + PORF Power-on Reset Flag + +SMCR Sleep Mode Control Register + SE Sleep Enable + SM2:0 + #define set_sleep_mode(mode) \ + #define SLEEP_MODE_IDLE (0) + #define SLEEP_MODE_ADC _BV(SM0) + #define SLEEP_MODE_PWR_DOWN _BV(SM1) + #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1)) + #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2)) + #define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2)) + + +ACSR Analog Comparator Control and Status Register + To disable Analog Comparator + ACSR = 0x80; + or + ACSR &= ~_BV(ACIE); + ACSR |= _BV(ACD); + + ACD: Analog Comparator Disable + When this bit is written logic one, the power to the Analog Comparator is + switched off. This bit can be set at any time to turn off the Analog + Comparator. This will reduce power consumption in Active and Idle mode. + When changing the ACD bit, the Analog Comparator Interrupt must be disabled + by clearing the ACIE bit in ACSR. Otherwise an interrupt can occur when + the bit is changed. + +DIDR1 Digital Input Disable Register 1 + AIN1D + AIN0D + When this bit is written logic one, the digital input buffer on the AIN1/0 pin is disabled. The corresponding PIN Register bit will always read as zero when this bit is set. When an analog signal is applied to the AIN1/0 pin and the digital input from this pin is not needed, this bit should be written logic one to reduce power consumption in the digital input buffer. + + +PRR Power Reduction Register + PRTWI + PRTIM2 + PRTIM0 + PRTIM1 + PRSPI + PRUSART0 + PRADC diff --git a/pr_checklist.md b/pr_checklist.md new file mode 100644 index 00000000000..22e8a3fe1a2 --- /dev/null +++ b/pr_checklist.md @@ -0,0 +1,128 @@ +# PR checklists + +This is a non-exhaustive checklist of what the QMK Collaborators will be checking when reviewing submitted PRs. + +If there are any inconsistencies with these recommendations, you're best off [creating an issue](https://github.com/qmk/qmk_firmware/issues/new) against this document, or getting in touch with a QMK Collaborator on [Discord](https://discord.gg/Uq7gcHh). + +## General PRs + +- PR should be submitted using a non-`master` branch on the source repository + - this does not mean you target a different branch for your PR, rather that you're not working out of your own master branch + - if submitter _does_ use their own `master` branch, they'll be given a link to the ["how to git"](https://docs.qmk.fm/#/newbs_git_using_your_master_branch) page after merging -- (end of this document will contain the contents of the message) +- newly-added directories and filenames must be lowercase + - this rule may be relaxed if upstream sources originally had uppercase characters (e.g. ChibiOS, or imported files from other repositories etc.) + - if there is enough justification (i.e. consistency with existing core files etc.) this can be relaxed + - a board designer naming their keyboard with uppercase letters is not enough justification +- valid license headers on all `*.c` and `*.h` source files + - GPL2/GPL3 recommended for consistency + - other licenses are permitted, however they must be GPL-compatible and must allow for redistribution. Using a different license will almost certainly delay a PR getting merged. +- QMK Codebase "best practices" followed + - this is not an exhaustive list, and will likely get amended as time goes by + - `#pragma once` instead of `#ifndef` include guards in header files + - no "old-school" GPIO/I2C/SPI functions used -- must use QMK abstractions unless justifiable (and laziness is not valid justification) + - timing abstractions should be followed too: + - `wait_ms()` instead of `_delay_ms()` (remove `#include ` too) + - `timer_read()` and `timer_read32()` etc. -- see [timer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/timer.h) for the timing APIs + - if you think a new abstraction is useful, you're encouraged to: + - prototype it in your own keyboard until it's feature-complete + - discuss it with QMK Collaborators on Discord + - refactor it as a separate core change + - remove your specific copy in your board +- rebase and fix all merge conflicts before opening the PR (in case you need help or advice, reach out to QMK Collaborators on Discord) + +## Keymap PRs + +- `#include QMK_KEYBOARD_H` preferred to including specific board files +- prefer layer `enum`s to `#define`s +- require custom keycode `enum`s to `#define`s, first entry must have ` = SAFE_RANGE` +- terminating backslash (`\`) in lines of LAYOUT macro parameters is superfluous +- some care with spacing (e.g., alignment on commas or first char of keycodes) makes for a much nicer-looking keymap + +## Keyboard PRs + +Closed PRs (for inspiration, previous sets of review comments will help you eliminate ping-pong of your own reviews): +https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard + +- `info.json` + - valid URL + - valid maintainer + - displays correctly in Configurator (press Ctrl+Shift+I to preview local file, turn on fast input to verify ordering) +- `readme.md` + - standard template should be present + - flash command has `:flash` at end + - valid hardware availability link (unless handwired) -- private groupbuys are okay, but one-off prototypes will be questioned. If open-source, a link to files should be provided. + - clear instructions on how to reset the board into bootloader mode + - a picture about the keyboard and preferably about the PCB, too +- `rules.mk` + - removed `MIDI_ENABLE`, `FAUXCLICKY_ENABLE` and `HD44780_ENABLE` + - modified `# Enable Bluetooth with the Adafruit EZ-Key HID` -> `# Enable Bluetooth` + - no `(-/+size)` comments related to enabling features + - remove the list of alternate bootloaders if one has been specified + - no re-definitions of the default MCU parameters if same value, when compared to the equivalent MCU in [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/quantum/mcu_selection.mk) +- keyboard `config.h` + - don't repeat `MANUFACTURER` in the `PRODUCT` value + - no `#define DESCRIPTION` + - no Magic Key Options, MIDI Options or HD44780 configuration + - user preference configurable `#define`s need to be moved to keymap `config.h` + - "`DEBOUNCE`" instead of "`DEBOUNCING_DELAY`" + - bare minimum required code for a board to boot into QMK should be present + - initialisation code for the matrix and critical devices + - mirroring existing functionality of a commercial board (like custom keycodes and special animations etc.) should be handled through non-`default` keymaps +- `keyboard.c` + - empty `xxxx_xxxx_kb()` or other weak-defined default implemented functions removed + - commented-out functions removed too + - `matrix_init_board()` etc. migrated to `keyboard_pre_init_kb()`, see: [keyboard_pre_init*](https://docs.qmk.fm/#/custom_quantum_functions?id=keyboard_pre_init_-function-documentation) + - prefer `CUSTOM_MATRIX = lite` if custom matrix used, allows for standard debounce, see [custom matrix 'lite'](https://docs.qmk.fm/#/custom_matrix?id=lite) +- `keyboard.h` + - `#include "quantum.h"` appears at the top + - `LAYOUT` macros should use standard definitions if applicable + - use the Community Layout macro names where they apply (preferred above `LAYOUT`/`LAYOUT_all`) +- keymap `config.h` + - no duplication of `rules.mk` or `config.h` from keyboard +- `keymaps/default/keymap.c` + - `QMKBEST`/`QMKURL` removed (sheesh) + - if using `MO(_LOWER)` and `MO(_RAISE)` keycodes or equivalent, and the keymap has an adjust layer when holding both keys -- if the keymap has no "direct-to-adjust" keycode (such as `MO(_ADJUST)`) then you should prefer to write... + ``` + layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); + } + ``` + ...instead of manually handling `layer_on()`, `update_tri_layer()` inside the keymap's `process_record_user()`. +- default (and via) keymaps should be "pristine" + - bare minimum to be used as a "clean slate" for another user to develop their own user-specific keymap + - standard layouts preferred in these keymaps, if possible +- submitters can have a personal (or bells-and-whistles) keymap showcasing capabilities in the same PR but it shouldn't be embedded in the 'default' keymap +- submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board + +Also, specific to ChibiOS: +- **strong** preference to using existing ChibiOS board definitions. + - a lot of the time, an equivalent Nucleo board can be used with a different flash size or slightly different model in the same family + - example: For an STM32L082KZ, given the similarity to an STM32L073RZ, you can use `BOARD = ST_NUCLEO64_L073RZ` in rules.mk + - QMK is migrating to not having custom board definitions if at all possible, due to the ongoing maintenance burden when upgrading ChibiOS +- if a board definition is unavoidable, `board.c` must have a standard `__early_init()` (as per normal ChibiOS board defs) and an empty `boardInit()`: + - see Arm/ChibiOS [early initialization](https://docs.qmk.fm/#/platformdev_chibios_earlyinit?id=board-init) + - `__early_init()` should be replaced by either `early_hardware_init_pre()` or `early_hardware_init_post()` as appropriate + - `boardInit()` should be migrated to `board_init()` + +## Core PRs + +- must now target `develop` branch, which will subsequently be merged back to `master` on the breaking changes timeline +- other notes TBD + - core is a lot more subjective given the breadth of posted changes + +--- + +## Notes + +For when people use their own `master` branch, post this after merge: +``` +For future reference, we recommend against committing to your `master` branch as you've done here, because pull requests from modified `master` branches can make it more difficult to keep your QMK fork updated. It is highly recommended for QMK development – regardless of what is being done or where – to keep your master updated, but **NEVER** commit to it. Instead, do all your changes in a branch (branches are basically free in Git) and issue PRs from your branches when you're developing. + +There are instructions on how to keep your fork updated here: + +[**Best Practices: Your Fork's Master: Update Often, Commit Never**](https://docs.qmk.fm/#/newbs_git_using_your_master_branch) + +[Fixing Your Branch](https://docs.qmk.fm/#/newbs_git_resynchronize_a_branch) will walk you through fixing up your `master` branch moving forward. If you need any help with this just ask. + +Thanks for contributing! +``` diff --git a/proton_c_conversion.md b/proton_c_conversion.md new file mode 100644 index 00000000000..1b5e496e74a --- /dev/null +++ b/proton_c_conversion.md @@ -0,0 +1,90 @@ +# Converting a board to use the Proton C + +Since the Proton C is a drop-in replacement for a Pro Micro we've made it easy to use. This page documents a handy automated process for converting keyboards, as well as documenting the manual process if you'd like to make use of Proton C features that aren't available on Pro Micros. + +## Automatic Conversion + +If a board currently supported in QMK uses a Pro Micro (or compatible board) and you want to use the Proton C, you can generate the firmware by appending `CONVERT_TO_PROTON_C=yes` (or `CTPC=yes`) to your make argument, like this: + + make 40percentclub/mf68:default CTPC=yes + +You can add the same argument to your keymap's `rules.mk`, which will accomplish the same thing. + +This exposes the `CONVERT_TO_PROTON_C` flag that you can use in your code with `#ifdef`s, like this: + +```c +#ifdef CONVERT_TO_PROTON_C + // Proton C code +#else + // Pro Micro code +#endif +``` + +If you get errors about `PORTB/DDRB`, etc not being defined, so you'll need to convert the keyboard's code to use the [GPIO Controls](internals_gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all. + +The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this like to your `config.h`: + + #define CONVERT_TO_PROTON_C_RXLED + +## Feature Conversion + +These are defaults based on what has been implemented for ARM boards. + +| Feature | Notes | +|-------------------------------------|------------------------------------------------------------------------------------------------------------------| +| [Audio](feature_audio.md) | Enabled | +| [RGB Lighting](feature_rgblight.md) | Disabled | +| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration | +| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | +| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features | + +## Manual Conversion + +To use the Proton C natively, without having to specify `CTPC=yes`, you need to change the `MCU` line in `rules.mk`: + +``` +MCU = STM32F303 +``` + +Remove these variables if they exist: + +* `BOOTLOADER` +* `EXTRA_FLAGS` + +Finally convert all pin assignments in `config.h` to the stm32 equivalents. + +| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right | +|-----------|----------|-|----------|-----------| +| `D3` | `A9` | | 5v | RAW (5v) | +| `D2` | `A10` | | GND | GND | +| GND | GND | | FLASH | RESET | +| GND | GND | | 3.3v | VCC 1 | +| `D1` | `B7` | | `A2` | `F4` | +| `D0` | `B6` | | `A1` | `F5` | +| `D4` | `B5` | | `A0` | `F6` | +| `C6` | `B4` | | `B8` | `F7` | +| `D7` | `B3` | | `B13` | `B1` | +| `E6` | `B2` | | `B14` | `B3` | +| `B4` | `B1` | | `B15` | `B2` | +| `B5` | `B0` | | `B9` | `B6` | +| `B0` (RX LED) | `C13` 2 | | `C13` 2 | `D5` (TX LED) | + +You can also make use of several new pins on the extended portion of the Proton C: + +| Left | | Right | +|------|-|-------| +| `A4`3 | | `B10` | +| `A5`4 | | `B11` | +| `A6` | | `B12` | +| `A7` | | `A14`5 (SWCLK) | +| `A8` | | `A13`5 (SWDIO) | +| `A15` | | RESET6 | + +Notes: + +1. On a Pro Micro VCC can be 3.3v or 5v. +2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`. +3. `A4` is shared with the speaker. +4. `A5` is shared with the speaker. +5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last. +6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU. diff --git a/pt-br/README.md b/pt-br/README.md new file mode 100644 index 00000000000..ea63ce13b5f --- /dev/null +++ b/pt-br/README.md @@ -0,0 +1,31 @@ +# Quantum Mechanical Keyboard Firmware + +[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## O que é o firmware QMK? +QMK (*Quantum Mechanical Keyboard*) é uma comunidade de código aberto que mantém o QMK Firmware, o QMK Toolbox, qmk.fm e suas documentações. O QMK Firmware é um software embarcado ("firmware") de teclado baseado no [tmk\_keyboard](http://github.com/tmk/tmk_keyboard) com alguns recursos úteis para os controladores Atmel AVR e, mais especificamente, na [linha de produtos OLKB](http://olkb.com), o teclado [ErgoDox EZ](http://www.ergodox-ez.com) e a [linha de produtos Clueboard](http://clueboard.co/). Também foi portado para chips ARM usando o ChibiOS. Você pode usá-lo no seu próprio teclado com fio ou personalizado. + +## Como obter e usar o QMK + +Se você planeja contribuir com um _keymap_ ("mapa de teclas"), teclado ou recursos para o QMK, o jeito mais fácil é [percorrer o repositório através do GitHub](https://github.com/qmk/qmk_firmware#fork-destination-box) e clonar seu repositório localmente para fazer suas alterações, dê um _push_ nelas e abra uma [_Pull request_](https://github.com/qmk/qmk_firmware/pulls) no seu fork. + +Caso contrário, você pode cloná-lo diretamente com `git clone https://github.com/qmk/qmk_firmware`. Não faça o download dos arquivos zip ou tar; é necessário um repositório git para baixar os submódulos para compilar. + +## Como compilar + +Antes de compilar, você precisará [instalar um ambiente específico](getting_started_build_tools.md) para o desenvolvimento em plataforma AVR e/ou ARM; vez que isto for feito, você usará o comando `make` para criar um teclado e um mapa de teclas com a seguinte notação: + + make planck/rev4:default + +Isso compilaria a revisão `rev4` do teclado ` planck` com o mapa de teclas `default`. Nem todos os teclados têm revisões (também chamadas de _subprojects_ ou _folders_); nesse caso, a revisão pode ser omitida: + + make preonic:default + +## Como personalizar + +O QMK tem muitos [recursos](features.md) para explorar e uma boa quantidade de [documentação de referência](http://docs.qmk.fm) para explorar. A maioria dos recursos é aproveitada modificando seu [keymap](keymap.md) e alterando os [keycodes](keycodes.md). diff --git a/pt-br/_summary.md b/pt-br/_summary.md new file mode 100644 index 00000000000..e0a1b45b331 --- /dev/null +++ b/pt-br/_summary.md @@ -0,0 +1,122 @@ +* [Complete Newbs Guide](pt-br/newbs.md) + * [Getting Started](pt-br/newbs_getting_started.md) + * [Building Your First Firmware](pt-br/newbs_building_firmware.md) + * [Flashing Firmware](pt-br/newbs_flashing.md) + * [Testing and Debugging](pt-br/newbs_testing_debugging.md) + * [Git Best Practices](pt-br/newbs_best_practices.md) + * [Learning Resources](pt-br/newbs_learn_more_resources.md) + +* [QMK Basics](pt-br/README.md) + * [QMK Introduction](pt-br/getting_started_introduction.md) + * [QMK CLI](pt-br/cli.md) + * [QMK CLI Config](pt-br/cli_configuration.md) + * [Contributing to QMK](pt-br/contributing.md) + * [How to Use GitHub](pt-br/getting_started_github.md) + * [Getting Help](pt-br/getting_started_getting_help.md) + +* [Breaking Changes](pt-br/breaking_changes.md) + * [2019 Aug 30](pt-br/ChangeLog/20190830.md) + +* [FAQ](faq.md) + * [General FAQ](pt-br/faq_general.md) + * [Build/Compile QMK](pt-br/faq_build.md) + * [Debugging/Troubleshooting QMK](pt-br/faq_debug.md) + * [Keymap](pt-br/faq_keymap.md) + * [Driver Installation with Zadig](pt-br/driver_installation_zadig.md) + +* Detailed Guides + * [Install Build Tools](pt-br/getting_started_build_tools.md) + * [Vagrant Guide](pt-br/getting_started_vagrant.md) + * [Build/Compile Instructions](pt-br/getting_started_make_guide.md) + * [Flashing Firmware](pt-br/flashing.md) + * [Customizing Functionality](pt-br/custom_quantum_functions.md) + * [Keymap Overview](pt-br/keymap.md) + +* [Hardware](hardware.md) + * [AVR Processors](pt-br/hardware_avr.md) + * [Drivers](pt-br/hardware_drivers.md) + +* Reference + * [Keyboard Guidelines](pt-br/hardware_keyboard_guidelines.md) + * [Config Options](pt-br/config_options.md) + * [Keycodes](pt-br/keycodes.md) + * [Coding Conventions - C](pt-br/coding_conventions_c.md) + * [Coding Conventions - Python](pt-br/coding_conventions_python.md) + * [Documentation Best Practices](pt-br/documentation_best_practices.md) + * [Documentation Templates](pt-br/documentation_templates.md) + * [Glossary](pt-br/reference_glossary.md) + * [Unit Testing](pt-br/unit_testing.md) + * [Useful Functions](pt-br/ref_functions.md) + * [Configurator Support](pt-br/reference_configurator_support.md) + * [info.json Format](pt-br/reference_info_json.md) + * [Python CLI Development](pt-br/cli_development.md) + +* [Features](pt-br/features.md) + * [Basic Keycodes](pt-br/keycodes_basic.md) + * [US ANSI Shifted Keys](pt-br/keycodes_us_ansi_shifted.md) + * [Quantum Keycodes](pt-br/quantum_keycodes.md) + * [Advanced Keycodes](pt-br/feature_advanced_keycodes.md) + * [Audio](pt-br/feature_audio.md) + * [Auto Shift](pt-br/feature_auto_shift.md) + * [Backlight](pt-br/feature_backlight.md) + * [Bluetooth](pt-br/feature_bluetooth.md) + * [Bootmagic](pt-br/feature_bootmagic.md) + * [Combos](pt-br/feature_combo.md) + * [Command](pt-br/feature_command.md) + * [Debounce API](pt-br/feature_debounce_type.md) + * [DIP Switch](pt-br/feature_dip_switch.md) + * [Dynamic Macros](pt-br/feature_dynamic_macros.md) + * [Encoders](pt-br/feature_encoders.md) + * [Grave Escape](pt-br/feature_grave_esc.md) + * [Haptic Feedback](pt-br/feature_haptic_feedback.md) + * [HD44780 LCD Controller](pt-br/feature_hd44780.md) + * [Key Lock](pt-br/feature_key_lock.md) + * [Layouts](pt-br/feature_layouts.md) + * [Leader Key](pt-br/feature_leader_key.md) + * [LED Matrix](pt-br/feature_led_matrix.md) + * [Macros](pt-br/feature_macros.md) + * [Mouse Keys](pt-br/feature_mouse_keys.md) + * [OLED Driver](pt-br/feature_oled_driver.md) + * [One Shot Keys](pt-br/one_shot_keys.md) + * [Pointing Device](pt-br/feature_pointing_device.md) + * [PS/2 Mouse](pt-br/feature_ps2_mouse.md) + * [RGB Lighting](pt-br/feature_rgblight.md) + * [RGB Matrix](pt-br/feature_rgb_matrix.md) + * [Space Cadet](pt-br/feature_space_cadet.md) + * [Split Keyboard](pt-br/feature_split_keyboard.md) + * [Stenography](pt-br/feature_stenography.md) + * [Swap Hands](pt-br/feature_swap_hands.md) + * [Tap Dance](pt-br/feature_tap_dance.md) + * [Terminal](pt-br/feature_terminal.md) + * [Thermal Printer](pt-br/feature_thermal_printer.md) + * [Unicode](pt-br/feature_unicode.md) + * [Userspace](pt-br/feature_userspace.md) + * [Velocikey](pt-br/feature_velocikey.md) + +* For Makers and Modders + * [Hand Wiring Guide](pt-br/hand_wire.md) + * [ISP Flashing Guide](pt-br/isp_flashing_guide.md) + * [ARM Debugging Guide](pt-br/arm_debugging.md) + * [I2C Driver](pt-br/i2c_driver.md) + * [SPI Driver](pt-br/spi_driver.md) + * [GPIO Controls](pt-br/internals_gpio_control.md) + * [Proton C Conversion](pt-br/proton_c_conversion.md) + +* For a Deeper Understanding + * [How Keyboards Work](pt-br/how_keyboards_work.md) + * [Understanding QMK](pt-br/understanding_qmk.md) + +* Other Topics + * [Using Eclipse with QMK](pt-br/other_eclipse.md) + * [Using VSCode with QMK](pt-br/other_vscode.md) + * [Support](pt-br/getting_started_getting_help.md) + * [How to add translations](pt-br/translating.md) + +* QMK Internals (In Progress) + * [Defines](pt-br/internals_defines.md) + * [Input Callback Reg](pt-br/internals_input_callback_reg.md) + * [Midi Device](pt-br/internals_midi_device.md) + * [Midi Device Setup Process](pt-br/internals_midi_device_setup_process.md) + * [Midi Util](pt-br/internals_midi_util.md) + * [Send Functions](pt-br/internals_send_functions.md) + * [Sysex Tools](pt-br/internals_sysex_tools.md) diff --git a/qmk.css b/qmk.css new file mode 100644 index 00000000000..543cd7f28d4 --- /dev/null +++ b/qmk.css @@ -0,0 +1,862 @@ +* { + -webkit-font-smoothing: antialiased; + -webkit-overflow-scrolling: touch; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-text-size-adjust: none; + -webkit-touch-callout: none; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +body:not(.ready) { + overflow: hidden; +} +body:not(.ready) [data-cloak], +body:not(.ready) .app-nav, +body:not(.ready) > nav { + display: none; +} +div#app { + font-size: 30px; + font-weight: lighter; + margin: 40vh auto; + text-align: center; +} +div#app:empty::before { + content: 'Loading...'; +} +.emoji { + height: 1.2rem; + vertical-align: middle; +} +.progress { + background-color: var(--theme-color, #ea6f5a); + height: 2px; + left: 0px; + position: fixed; + right: 0px; + top: 0px; + -webkit-transition: width 0.2s, opacity 0.4s; + transition: width 0.2s, opacity 0.4s; + width: 0%; + z-index: 999999; +} +.search a:hover { + color: var(--theme-color, #ea6f5a); +} +.search .search-keyword { + color: var(--theme-color, #ea6f5a); + font-style: normal; + font-weight: bold; +} +html, +body { + height: 100%; +} +body { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: #efefef; + font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + font-size: 15px; + letter-spacing: 0; + margin: 0; + overflow-x: hidden; +} +img { + max-width: 100%; +} +a[disabled] { + cursor: not-allowed; + opacity: 0.6; +} +kbd { + border: solid 1px #ccc; + border-radius: 3px; + display: inline-block; + font-size: 12px !important; + line-height: 12px; + margin-bottom: 3px; + padding: 3px 5px; + vertical-align: middle; +} +.task-list-item { + list-style-type: none; +} +li input[type='checkbox'] { + margin: 0 0.2em 0.25em -1.6em; + vertical-align: middle; +} +.app-nav { + margin: 25px 60px 0 0; + position: absolute; + right: 0; + text-align: right; + z-index: 10; +/* navbar dropdown */ +} +.app-nav.no-badge { + margin-right: 25px; +} +.app-nav p { + margin: 0; +} +.app-nav > a { + margin: 0 1rem; + padding: 5px 0; +} +.app-nav ul, +.app-nav li { + display: inline-block; + list-style: none; + margin: 0; +} +.app-nav a { + color: inherit; + font-size: 16px; + text-decoration: none; + -webkit-transition: color 0.3s; + transition: color 0.3s; +} +.app-nav a:hover { + color: var(--theme-color, #ea6f5a); +} +.app-nav a.active { + border-bottom: 2px solid var(--theme-color, #ea6f5a); + color: var(--theme-color, #ea6f5a); +} +.app-nav li { + display: inline-block; + margin: 0 1rem; + padding: 5px 0; + position: relative; +} +.app-nav li ul { + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: #ccc; + border-radius: 4px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + display: none; + max-height: calc(100vh - 61px); + overflow-y: auto; + padding: 10px 0; + position: absolute; + right: -15px; + text-align: left; + top: 100%; + white-space: nowrap; +} +.app-nav li ul li { + display: block; + font-size: 14px; + line-height: 1rem; + margin: 0; + margin: 8px 14px; + white-space: nowrap; +} +.app-nav li ul a { + display: block; + font-size: inherit; + margin: 0; + padding: 0; +} +.app-nav li ul a.active { + border-bottom: 0; +} +.app-nav li:hover ul { + display: block; +} +.github-corner { + border-bottom: 0; + position: fixed; + right: 0; + text-decoration: none; + top: 0; + z-index: 1; +} +.github-corner:hover .octo-arm { + -webkit-animation: octocat-wave 560ms ease-in-out; + animation: octocat-wave 560ms ease-in-out; +} +.github-corner svg { + color: #3f3f3f; + fill: var(--theme-color, #ea6f5a); + height: 80px; + width: 80px; +} +main { + display: block; + position: relative; + width: 100vw; + height: 100%; + z-index: 0; +} +main.hidden { + display: none; +} +.anchor { + display: inline-block; + text-decoration: none; + -webkit-transition: all 0.3s; + transition: all 0.3s; +} +.anchor span { + color: #c8c8c8; +} +.anchor:hover { + text-decoration: underline; +} +.sidebar { + border-right: 1px solid rgba(0,0,0,0.07); + overflow-y: auto; + padding: 40px 0 0; + position: absolute; + top: 0; + bottom: 0; + left: 0; + -webkit-transition: -webkit-transform 250ms ease-out; + transition: -webkit-transform 250ms ease-out; + transition: transform 250ms ease-out; + transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; + width: 300px; + z-index: 20; +} +.sidebar > h1 { + margin: 0 auto 1rem; + font-size: 1.5rem; + font-weight: 300; + text-align: center; +} +.sidebar > h1 a { + color: inherit; + text-decoration: none; +} +.sidebar > h1 .app-nav { + display: block; + position: static; +} +.sidebar .sidebar-nav { + line-height: 2em; + padding-bottom: 40px; +} +.sidebar li.collapse .app-sub-sidebar { + display: none; +} +.sidebar ul { + margin: 0; + padding: 0; +} +.sidebar li > p { + font-weight: 700; + margin: 0; +} +.sidebar ul, +.sidebar ul li { + list-style: none; +} +.sidebar ul li a { + border-bottom: none; + display: block; +} +.sidebar ul li ul { + padding-left: 20px; +} +.sidebar::-webkit-scrollbar { + width: 4px; +} +.sidebar::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 4px; +} +.sidebar:hover::-webkit-scrollbar-thumb { + background: rgba(136,136,136,0.4); +} +.sidebar:hover::-webkit-scrollbar-track { + background: rgba(136,136,136,0.1); +} +.sidebar-toggle { + background-color: transparent; + background-color: rgba(63,63,63,0.8); + border: 0; + outline: none; + padding: 10px; + position: absolute; + bottom: 0; + left: 0; + text-align: center; + -webkit-transition: opacity 0.3s; + transition: opacity 0.3s; + width: 284px; + z-index: 30; +} +.sidebar-toggle .sidebar-toggle-button:hover { + opacity: 0.4; +} +.sidebar-toggle span { + background-color: var(--theme-color, #ea6f5a); + display: block; + margin-bottom: 4px; + width: 16px; + height: 2px; +} +body.sticky .sidebar, +body.sticky .sidebar-toggle { + position: fixed; +} +.content { + padding-top: 60px; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 300px; + -webkit-transition: left 250ms ease; + transition: left 250ms ease; +} +.markdown-section { + margin: 0 auto; + max-width: 800px; + padding: 30px 15px 40px 15px; + position: relative; +} +.markdown-section > * { + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-size: inherit; +} +.markdown-section > :first-child { + margin-top: 0 !important; +} +.markdown-section hr { + border: none; + border-bottom: 1px solid #eee; + margin: 2em 0; +} +.markdown-section iframe { + border: 1px solid #eee; +} +.markdown-section table { + border-collapse: collapse; + border-spacing: 0; + display: block; + margin-bottom: 1rem; + overflow: auto; + width: 100%; +} +.markdown-section th { + border: 1px solid #ddd; + font-weight: bold; + padding: 6px 13px; +} +.markdown-section td { + border: 1px solid #ddd; + padding: 6px 13px; +} +.markdown-section tr { + border-top: 1px solid #ccc; +} +.markdown-section tr:nth-child(2n) { + background-color: #555555; +} +.markdown-section p.tip { + background-color: #555555; + border-bottom-right-radius: 2px; + border-left: 4px solid #f66; + border-top-right-radius: 2px; + margin: 2em 0; + padding: 12px 24px 12px 30px; + position: relative; +} +.markdown-section p.tip:before { + background-color: #f66; + border-radius: 100%; + color: #3f3f3f; + content: '!'; + font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + font-size: 14px; + font-weight: bold; + left: -12px; + line-height: 20px; + position: absolute; + height: 20px; + width: 20px; + text-align: center; + top: 14px; +} +.markdown-section p.tip code { + background-color: #efefef; +} +.markdown-section p.tip em { + color: #c8c8c8; +} +.markdown-section p.warn { + background: rgba(234,111,90,0.1); + border-radius: 2px; + padding: 1rem; +} +body.close .sidebar { + -webkit-transform: translateX(-300px); + transform: translateX(-300px); +} +body.close .sidebar-toggle { + width: auto; +} +body.close .content { + left: 0; +} +@media print { + .github-corner, + .sidebar-toggle, + .sidebar, + .app-nav { + display: none; + } +} +@media screen and (max-width: 768px) { + .github-corner, + .sidebar-toggle, + .sidebar { + position: fixed; + } + .app-nav { + margin-top: 16px; + } + .app-nav li ul { + top: 30px; + } + main { + height: auto; + overflow-x: hidden; + } + .sidebar { + left: -300px; + -webkit-transition: -webkit-transform 250ms ease-out; + transition: -webkit-transform 250ms ease-out; + transition: transform 250ms ease-out; + transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; + } + .content { + left: 0; + max-width: 100vw; + position: static; + padding-top: 20px; + -webkit-transition: -webkit-transform 250ms ease; + transition: -webkit-transform 250ms ease; + transition: transform 250ms ease; + transition: transform 250ms ease, -webkit-transform 250ms ease; + } + .app-nav, + .github-corner { + -webkit-transition: -webkit-transform 250ms ease-out; + transition: -webkit-transform 250ms ease-out; + transition: transform 250ms ease-out; + transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; + } + .sidebar-toggle { + background-color: transparent; + width: auto; + padding: 30px 30px 10px 10px; + } + body.close .sidebar { + -webkit-transform: translateX(300px); + transform: translateX(300px); + } + body.close .sidebar-toggle { + background-color: rgba(63,63,63,0.8); + -webkit-transition: 1s background-color; + transition: 1s background-color; + width: 284px; + padding: 10px; + } + body.close .content { + -webkit-transform: translateX(300px); + transform: translateX(300px); + } + body.close .app-nav, + body.close .github-corner { + display: none; + } + .github-corner:hover .octo-arm { + -webkit-animation: none; + animation: none; + } + .github-corner .octo-arm { + -webkit-animation: octocat-wave 560ms ease-in-out; + animation: octocat-wave 560ms ease-in-out; + } +} +@-webkit-keyframes octocat-wave { + 0%, 100% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 20%, 60% { + -webkit-transform: rotate(-25deg); + transform: rotate(-25deg); + } + 40%, 80% { + -webkit-transform: rotate(10deg); + transform: rotate(10deg); + } +} +@keyframes octocat-wave { + 0%, 100% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 20%, 60% { + -webkit-transform: rotate(-25deg); + transform: rotate(-25deg); + } + 40%, 80% { + -webkit-transform: rotate(10deg); + transform: rotate(10deg); + } +} +section.cover { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + height: 100vh; + display: none; +} +section.cover.show { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +section.cover.has-mask .mask { + background-color: #3f3f3f; + opacity: 0.8; + position: absolute; + top: 0; + height: 100%; + width: 100%; +} +section.cover .cover-main { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + margin: -20px 16px 0; + text-align: center; + z-index: 1; +} +section.cover a { + color: inherit; + text-decoration: none; +} +section.cover a:hover { + text-decoration: none; +} +section.cover p { + line-height: 1.5rem; + margin: 1em 0; +} +section.cover h1 { + color: inherit; + font-size: 2.5rem; + font-weight: 300; + margin: 0.625rem 0 2.5rem; + position: relative; + text-align: center; +} +section.cover h1 a { + display: block; +} +section.cover h1 small { + bottom: -0.4375rem; + font-size: 1rem; + position: absolute; +} +section.cover blockquote { + font-size: 1.5rem; + text-align: center; +} +section.cover ul { + line-height: 1.8; + list-style-type: none; + margin: 1em auto; + max-width: 500px; + padding: 0; +} +section.cover .cover-main > p:last-child a { + border-color: var(--theme-color, #ea6f5a); + border-radius: 2rem; + border-style: solid; + border-width: 1px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: var(--theme-color, #ea6f5a); + display: inline-block; + font-size: 1.05rem; + letter-spacing: 0.1rem; + margin: 0.5rem 1rem; + padding: 0.75em 2rem; + text-decoration: none; + -webkit-transition: all 0.15s ease; + transition: all 0.15s ease; +} +section.cover .cover-main > p:last-child a:last-child { + background-color: var(--theme-color, #ea6f5a); + color: #fff; +} +section.cover .cover-main > p:last-child a:last-child:hover { + color: inherit; + opacity: 0.8; +} +section.cover .cover-main > p:last-child a:hover { + color: inherit; +} +section.cover blockquote > p > a { + border-bottom: 2px solid var(--theme-color, #ea6f5a); + -webkit-transition: color 0.3s; + transition: color 0.3s; +} +section.cover blockquote > p > a:hover { + color: var(--theme-color, #ea6f5a); +} +body { + background-color: #3f3f3f; +} +/* sidebar */ +.sidebar { + background-color: #3f3f3f; + color: #c8c8c8; +} +.sidebar li { + margin: 6px 15px; +} +.sidebar ul li a { + color: #c8c8c8; + font-size: 14px; + overflow: hidden; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; +} +.sidebar ul li a:hover { + text-decoration: underline; +} +.sidebar ul li ul { + padding: 0; +} +.sidebar ul li.active > a { + color: var(--theme-color, #ea6f5a); + font-weight: 600; +} +/* markdown content found on pages */ +.markdown-section h1, +.markdown-section h2, +.markdown-section h3, +.markdown-section h4, +.markdown-section strong { + color: #657b83; + font-weight: 600; +} +.markdown-section a { + color: var(--theme-color, #ea6f5a); + font-weight: 600; +} +.markdown-section h1 { + font-size: 2rem; + margin: 0 0 1rem; +} +.markdown-section h2 { + font-size: 1.75rem; + margin: 45px 0 0.8rem; +} +.markdown-section h3 { + font-size: 1.5rem; + margin: 40px 0 0.6rem; +} +.markdown-section h4 { + font-size: 1.25rem; +} +.markdown-section h5 { + font-size: 1rem; +} +.markdown-section h6 { + color: #777; + font-size: 1rem; +} +.markdown-section figure, +.markdown-section p, +.markdown-section ul, +.markdown-section ol { + margin: 1.2em 0; +} +.markdown-section p, +.markdown-section ul, +.markdown-section ol { + line-height: 1.6rem; + word-spacing: 0.05rem; +} +.markdown-section ul, +.markdown-section ol { + padding-left: 1.5rem; +} +.markdown-section blockquote { + border-left: 4px solid var(--theme-color, #ea6f5a); + color: #858585; + margin: 2em 0; + padding-left: 20px; +} +.markdown-section blockquote p { + font-weight: 600; + margin-left: 0; +} +.markdown-section iframe { + margin: 1em 0; +} +.markdown-section em { + color: #7f8c8d; +} +.markdown-section code { + background-color: #282828; + border-radius: 2px; + color: #aaaaaa; + font-family: 'Roboto Mono', Monaco, courier, monospace; + font-size: 0.8rem; + margin: 0 2px; + padding: 3px 5px; + white-space: pre-wrap; +} +.markdown-section pre { + -moz-osx-font-smoothing: initial; + -webkit-font-smoothing: initial; + background-color: #282828; + font-family: 'Roboto Mono', Monaco, courier, monospace; + line-height: 1.5rem; + margin: 1.2em 0; + overflow: auto; + padding: 0 1.4rem; + position: relative; + word-wrap: normal; +} +/* code highlight */ +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #8e908c; +} +.token.namespace { + opacity: 0.7; +} +.token.boolean, +.token.number { + color: #c76b29; +} +.token.punctuation { + color: #525252; +} +.token.property { + color: #c08b30; +} +.token.tag { + color: #2973b7; +} +.token.string { + color: var(--theme-color, #ea6f5a); +} +.token.selector { + color: #6679cc; +} +.token.attr-name { + color: #2973b7; +} +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #22a2c9; +} +.token.attr-value, +.token.control, +.token.directive, +.token.unit { + color: var(--theme-color, #ea6f5a); +} +.token.keyword { + color: #e96900; +} +.token.statement, +.token.regex, +.token.atrule { + color: #22a2c9; +} +.token.placeholder, +.token.variable { + color: #3d8fd1; +} +.token.deleted { + text-decoration: line-through; +} +.token.inserted { + border-bottom: 1px dotted #202746; + text-decoration: none; +} +.token.italic { + font-style: italic; +} +.token.important, +.token.bold { + font-weight: bold; +} +.token.important { + color: #c94922; +} +.token.entity { + cursor: help; +} +.markdown-section pre > code { + -moz-osx-font-smoothing: initial; + -webkit-font-smoothing: initial; + background-color: #282828; + border-radius: 2px; + color: #657b83; + display: block; + font-family: 'Roboto Mono', Monaco, courier, monospace; + font-size: 0.8rem; + line-height: inherit; + margin: 0 2px; + max-width: inherit; + overflow: inherit; + padding: 2.2em 5px; + white-space: inherit; +} +.markdown-section code::after, +.markdown-section code::before { + letter-spacing: 0.05rem; +} +code .token { + -moz-osx-font-smoothing: initial; + -webkit-font-smoothing: initial; + min-height: 1.5rem; +} +pre::after { + color: #ccc; + content: attr(data-lang); + font-size: 0.6rem; + font-weight: 600; + height: 15px; + line-height: 15px; + padding: 5px 10px 0; + position: absolute; + right: 0; + text-align: right; + top: 0; +} +.markdown-section p.tip { + background-color: #282828; + color: #657b83; +} +input[type='search'] { + background: #4f4f4f; + border-color: #4f4f4f; + color: #c8c8c8; +} diff --git a/qmk_custom_dark.css b/qmk_custom_dark.css new file mode 100644 index 00000000000..a7feb159c80 --- /dev/null +++ b/qmk_custom_dark.css @@ -0,0 +1,29 @@ +.sidebar li.active { + background-color: #555; +} + +.markdown-section p.tip, +.markdown-section tr:nth-child(2n) { + background-color:#444; +} + +.markdown-section tr { + border-top: 1px solid #555; +} + +.markdown-section td, .markdown-section th { + border: 1px solid #555; +} + +.markdown-section p.tip code { + background-color: #555; + color: #fff; +} + +.page_toc code { + background-color: #555; +} + +.markdown-section hr, .search { + border-bottom: 1px solid #777 !important; +} diff --git a/qmk_custom_light.css b/qmk_custom_light.css new file mode 100644 index 00000000000..07b26ecec96 --- /dev/null +++ b/qmk_custom_light.css @@ -0,0 +1,30 @@ +.sidebar-toggle { + position: absolute; + top: 0; + bottom: auto; + left: 0; +} + +.search { + margin-top: 40px; +} + +.markdown-section h2 { + padding-top: 0.25rem; +} + +.markdown-section h3 { + margin-top: 0.25rem; +} + +.sidebar, .sidebar-nav { + line-height: 1.5em !important; +} + +.markdown-section ul ul { + margin: 0; +} + +.markdown-section pre { + padding: 0; +} diff --git a/quantum_keycodes.md b/quantum_keycodes.md new file mode 100644 index 00000000000..7ebad2c1ee1 --- /dev/null +++ b/quantum_keycodes.md @@ -0,0 +1,15 @@ +# Quantum Keycodes + +Quantum keycodes allow for easier customization of your keymap than the basic ones provide, without having to define custom actions. + +All keycodes within quantum are numbers between `0x0000` and `0xFFFF`. Within your `keymap.c` it may look like you have functions and other special cases, but ultimately the C preprocessor will translate those into a single 4 byte integer. QMK has reserved `0x0000` through `0x00FF` for standard keycodes. These are keycodes such as `KC_A`, `KC_1`, and `KC_LCTL`, which are basic keys defined in the USB HID specification. + +On this page we have documented keycodes between `0x00FF` and `0xFFFF` which are used to implement advanced quantum features. If you define your own custom keycodes they will be put into this range as well. + +## QMK Keycodes :id=qmk-keycodes + +|Key |Aliases |Description | +|--------------|---------|-------------------------------------------------------| +|`RESET` | |Put the keyboard into bootloader mode for flashing | +|`DEBUG` | |Toggle debug mode | +|`EEPROM_RESET`|`EEP_RST`|Reinitializes the keyboard's EEPROM (persistent memory)| diff --git a/redirects.json b/redirects.json new file mode 100644 index 00000000000..651148c2c12 --- /dev/null +++ b/redirects.json @@ -0,0 +1,52 @@ +{ + "redirects": [ + { + "from": "adding_a_keyboard_to_qmk.html", + "to": "hardware_keyboard_guidelines.html" + }, + { + "from": "build_environment_setup.html", + "to": "getting_started_build_tools.html" + }, + { + "from": "dynamic_macros.html", + "to": "feature_dynamic_macros.html" + }, + { + "from": "feature_common_shortcuts.html", + "to": "feature_advanced_keycodes.html" + }, + { + "from": "glossary.html", + "to": "reference_glossary.html" + }, + { + "from": "key_lock.html", + "to": "feature_key_lock.html" + }, + { + "from": "make_instructions.html", + "to": "getting_started_make_guide.html" + }, + { + "from": "porting_your_keyboard_to_qmk.html", + "to": "hardware_avr.html" + }, + { + "from": "space_cadet_shift.html", + "to": "feature_space_cadet_shift.html" + }, + { + "from": "tap_dance.html", + "to": "feature_tap_dance.html" + }, + { + "from": "unicode.html", + "to": "feature_unicode.html" + }, + { + "from": "python_development.html", + "to": "cli_development.html" + } + ] +} diff --git a/ref_functions.md b/ref_functions.md new file mode 100644 index 00000000000..176095070b1 --- /dev/null +++ b/ref_functions.md @@ -0,0 +1,119 @@ +# List of Useful Core Functions To Make Your Keyboard Better + +There are a lot of hidden functions in QMK that are incredible useful, or may add a bit of functionality that you've been wanting. Functions that are specific to certain features are not included here, as those will be on their respective feature page. + +## (OLKB) Tri Layers :id=olkb-tri-layers + +There are actually separate functions that you can use there, depending on what you're after. + +### `update_tri_layer(x, y, z)` + +The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it turns on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it turns off layer `z`. + +This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this. + +#### Example + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LOWER: + if (record->event.pressed) { + layer_on(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_LOWER); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + case RAISE: + if (record->event.pressed) { + layer_on(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } else { + layer_off(_RAISE); + update_tri_layer(_LOWER, _RAISE, _ADJUST); + } + return false; + } + return true; +} +``` + +### `update_tri_layer_state(state, x, y, z)` +The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from the [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check. + +There are a couple of caveats to this method: +1. You cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it. +2. Because layers are processed from the highest number `z` should be a higher layer than `x` and `y` or you may not be able to access it. + +#### Example + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} +``` + +Alternatively, you don't have to immediately "return" the value. This is useful if you want to add multiple tri layers, or if you want to add additional effects. + +```c +layer_state_t layer_state_set_user(layer_state_t state) { + state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); + state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL); + return state; +} +``` + +## Setting the Persistent Default Layer + +Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you. + +To use this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK). + +This will set the default layer, update the persistent settings, and play a tune if you have [Audio](feature_audio.md) enabled on your board, and the default layer sounds set. + +To configure the default layer sounds, you would want to define this in your `config.h` file, like this: + +```c +#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +``` + + +?> There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use. + +## Reseting the keyboard + +There is the `RESET` quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that. + +And to do so, add `reset_keyboard()` to your function or macro, and this will reset to bootloader. + +## Wiping the EEPROM (Persistent Storage) + +If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). Bootmagic is one way to do this, but if that isn't enabled, then you can use a custom macro to do so. + +To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default. + +## Tap random key + +If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`). + +?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords. + +## Software Timers + +It's possible to start timers and read values for time-specific events. Here's an example: + +```c +static uint16_t key_timer; +key_timer = timer_read(); + +if (timer_elapsed(key_timer) < 100) { + // do something if less than 100ms have passed +} else { + // do something if 100ms or more have passed +} +``` diff --git a/reference_configurator_support.md b/reference_configurator_support.md new file mode 100644 index 00000000000..88676ba9733 --- /dev/null +++ b/reference_configurator_support.md @@ -0,0 +1,197 @@ +# Supporting Your Keyboard in QMK Configurator + +This page covers how to properly support keyboards in the [QMK Configurator](https://config.qmk.fm/). + + +## How the Configurator Understands Keyboards + +To understand how the Configurator understands keyboards, first one must understand layout macros. For this exercise, we're going to imagine a 17-key numpad PCB, which we're going to call `numpad`. + +``` +|---------------| +|NLk| / | * | - | +|---+---+---+---| +|7 |8 |9 | + | +|---+---+---| | +|4 |5 |6 | | +|---+---+---+---| +|1 |2 |3 |Ent| +|-------+---| | +|0 | . | | +|---------------| +``` + +?> For more on layout macros, see [Understanding QMK: Matrix Scanning](understanding_qmk.md?id=matrix-scanning) and [Understanding QMK: Matrix to Physical Layout Map](understanding_qmk.md?id=matrix-to-physical-layout-map). + +The Configurator's API reads the keyboard's `.h` file from `qmk_firmware/keyboards//.h`. For our numpad, this file would be `qmk_firmware/keyboards/numpad/numpad.h`: + +```c +#pragma once + +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ + ) { \ + { k00, k01, k02, k03 }, \ + { k10, k11, k12, k13 }, \ + { k20, k21, k22, KC_NO }, \ + { k30, k31, k32, k33 }, \ + { k40, KC_NO, k42, KC_NO } \ +} +``` + +QMK uses `KC_NO` to designate places in the switch matrix where there is no switch. Sometimes, `XXX`, `___` or `____` are used as shorthand to make this section easier to read if it needs to be debugged. This is usually defined near the beginning of the `.h` file: + +```c +#pragma once + +#define XXX KC_NO + +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ + ) { \ + { k00, k01, k02, k03 }, \ + { k10, k11, k12, k13 }, \ + { k20, k21, k22, XXX }, \ + { k30, k31, k32, k33 }, \ + { k40, XXX, k42, XXX } \ +} +``` + +!> This usage differs from that of keymap macros, which almost always use `XXXXXXX` (seven capital X's) for `KC_NO` and `_______` (seven underscores) for `KC_TRNS`. + +!> To prevent user confusion, using `KC_NO` is preferred. + +The layout macro tells the Configurator that our keyboard has 17 keys, arranged in five rows of four columns each. Our switch positions are named `k`, counting from 0. The names themselves actually don't matter, as long as they match between the top section, which receives the keycodes from the keymap, and the bottom half which designates where each key is in the matrix. + +To display our keyboard in a way that resembles the physical keyboard, we need to build a JSON file that tells the Configurator how to tie the physical locations and sizes of our keys to our switch matrix. + +## Building the JSON file + +To build the JSON file, the easiest way is to build the layout in [Keyboard Layout Editor](http://www.keyboard-layout-editor.com/) ("KLE"), from which we'll feed the Raw Data into a QMK tool that converts this data into a JSON the Configurator will read and use. Since KLE opens by default with a numpad layout, we're just going to remove the Getting Started instructions, and use what's left. + +Once the layout is as desired, move to the Raw Data tab in KLE, and copy the contents: + +``` +["Num Lock","/","*","-"], +["7\nHome","8\n↑","9\nPgUp",{h:2},"+"], +["4\n←","5","6\n→"], +["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"], +[{w:2},"0\nIns",".\nDel"] +``` + +To convert this data into our JSON, go to the [QMK KLE-JSON Converter](https://qmk.fm/converter/), paste the Raw Data into the Input field, and click the Convert button. After a moment, our JSON data will appear in the Output field. Copy the contents to a new text document, and name the document `info.json`, saving it in the same folder that contains `numpad.h`. + +Use the `keyboard_name` object to set the name of the keyboard. For instruction purposes, we will put each key's object on its own line. This is only to make the file more human-readable, and does not affect the Configurator's functionality. + +```json +{ + "keyboard_name": "Numpad", + "url": "", + "maintainer": "qmk", + "tags": { + "form_factor": "numpad" + }, + "width": 4, + "height": 5, + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"Num Lock", "x":0, "y":0}, + {"label":"/", "x":1, "y":0}, + {"label":"*", "x":2, "y":0}, + {"label":"-", "x":3, "y":0}, + {"label":"7", "x":0, "y":1}, + {"label":"8", "x":1, "y":1}, + {"label":"9", "x":2, "y":1}, + {"label":"+", "x":3, "y":1, "h":2}, + {"label":"4", "x":0, "y":2}, + {"label":"5", "x":1, "y":2}, + {"label":"6", "x":2, "y":2}, + {"label":"1", "x":0, "y":3}, + {"label":"2", "x":1, "y":3}, + {"label":"3", "x":2, "y":3}, + {"label":"Enter", "x":3, "y":3, "h":2}, + {"label":"0", "x":0, "y":4, "w":2}, + {"label":".", "x":2, "y":4} + ] + } + } +} +``` + +The `layouts` object contains the data that represents the physical layout of the keyboard. It has an object `LAYOUT`, which needs to match the name of our layout macro from `numpad.h`. The `LAYOUT` object itself has an object named `layout`, which contains one JSON object for each physical key on our keyboard, formatted as follows: + +``` + The name of the key. Not displayed in the Configurator. + | + | The key's X-axis location, in key units from the + | | keyboard's left edge. + | | + | | The key's Y-axis location, in key units from + | | | the keyboard's top (rear-facing) edge. + ↓ ↓ ↓ +{"label":"Num Lock", "x":0, "y":0}, +``` + +Some objects will also have `"w"` and `"h"` keys, which represent a key's width and height, respectively. + +?> For more on the `info.json` files, see [`info.json` Format](reference_info_json.md). + + +## How the Configurator Programs Keys + +The Configurator's API uses the layout macro and the JSON file we've given it to create a visual representation of the keyboard that has each visual object tied to a specific key, in sequence: + +key in layout macro | JSON object used +:---: | :---- +k00 | {"label":"Num Lock", "x":0, "y":0} +k01 | {"label":"/", "x":1, "y":0} +k02 | {"label":"*", "x":2, "y":0} +k03 | {"label":"-", "x":3, "y":0} +k10 | {"label":"7", "x":0, "y":1} +k11 | {"label":"8", "x":1, "y":1} +k12 | {"label":"9", "x":2, "y":1} +k13 | {"label":"+", "x":3, "y":1, "h":2} +k20 | {"label":"4", "x":0, "y":2} +k21 | {"label":"5", "x":1, "y":2} +k22 | {"label":"6", "x":2, "y":2} +k30 | {"label":"1", "x":0, "y":3} +k31 | {"label":"2", "x":1, "y":3} +k32 | {"label":"3", "x":2, "y":3} +k33 | {"label":"Enter", "x":3, "y":3, "h":2} +k40 | {"label":"0", "x":0, "y":4, "w":2} +k42 | {"label":".", "x":2, "y":4} + +When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the Configurator builds a keymap file with `KC_NLCK` as the first key, and so on as the keymap is built. The `label` keys are not used; they are only for the user's reference in identifying specific keys when debugging the `info.json` file. + + +## Issues and Hazards + +Currently, the Configurator does not support key rotation or non-rectangular key shapes like ISO Enter. Additionally, keys that are vertically-offset from their "row" — the arrow keys on 1800-layouts like the [TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/) being a prominent example — confuse the KLE-to-JSON Converter, if not adjusted for by the contributor of the `info.json` file. + +### Workarounds + +#### Non-rectangular keys + +For ISO Enter keys, QMK custom is to display it as a rectangular key, 1.25u wide and 2u high, aligned so its right edge is aligned with the right edge of the alphanumeric key block. + +![](https://i.imgur.com/JKngtTw.png) +*A 60% keyboard in standard ISO layout, as rendered by QMK Configurator.* + +#### Vertically-offset keys + +For vertically-offset keys, place them in KLE as if they were not offset, then edit the Y-values as needed in the converted JSON file + +![](https://i.imgur.com/fmDvDzR.png) +*An 1800-layout keyboard as rendered in Keyboard Layout Editor, without the vertical offset applied to the arrow keys.* + +![](https://i.imgur.com/8beYMBR.png) +*A Unix diff file, showing the changes needed to vertically-offset the arrow keys in our keyboard's JSON file.* diff --git a/reference_glossary.md b/reference_glossary.md new file mode 100644 index 00000000000..1da27ff24fd --- /dev/null +++ b/reference_glossary.md @@ -0,0 +1,167 @@ +# Glossary of QMK Terms + +## ARM +A line of 32-bit MCUs produced by a number of companies, such as Atmel, Cypress, Kinetis, NXP, ST, and TI. + +## AVR +A line of 8-bit MCUs produced by [Atmel](http://www.microchip.com/). AVR was the original platform that TMK supported. + +## AZERTY +The standard Français (French) keyboard layout. Named for the first 6 keys on the keyboard. + +## Backlight +A generic term for lighting on a keyboard. The backlight is typically, but not always, an array of LEDs that shine through keycaps and/or switches. + +## Bluetooth +A short range peer to peer wireless protocol. Most common wireless protocol for a keyboard. + +## Bootloader +A special program that is written to a protected area of your MCU that allows the MCU to upgrade its own firmware, typically over USB. + +## Bootmagic +A feature that allows for various keyboard behavior changes to happen on the fly, such as swapping or disabling common keys. + +## C +A low-level programming language suitable for system code. Most QMK code is written in C. + +## Colemak +An alternative keyboard layout that is gaining in popularity. + +## Compile +The process of turning human readable code into machine code your MCU can run. + +## Dvorak +An alternative keyboard layout developed by Dr. August Dvorak in the 1930's. A shortened form of the Dvorak Simplified Keyboard. + +## Dynamic Macro +A macro which has been recorded on the keyboard and which will be lost when the keyboard is unplugged or the computer rebooted. + +* [Dynamic Macro Documentation](feature_dynamic_macros.md) + +## Eclipse +An IDE that is popular with many C developers. + +* [Eclipse Setup Instructions](other_eclipse.md) + +## Firmware +The software that controls your MCU. + +## git +Versioning software used at the command line + +## GitHub +The website that hosts most of the QMK project. It provides integration with git, issue tracking, and other features that help us run QMK. + +## ISP +In-system programming, a method of programming an AVR chip using external hardware and the JTAG pins. + +## hid_listen +An interface for receiving debugging messages from your keyboard. You can view these messages using [QMK Flasher](https://github.com/qmk/qmk_flasher) or [PJRC's hid_listen](https://www.pjrc.com/teensy/hid_listen.html) + +## Keycode +A 2-byte number that represents a particular key. `0x00`-`0xFF` are used for [Basic Keycodes](keycodes_basic.md) while `0x100`-`0xFFFF` are used for [Quantum Keycodes](quantum_keycodes.md). + +## Key Down +An event that happens when a key is pressed down, but is completed before a key is released. + +## Key Up +An event that happens when a key is released. + +## Keymap +An array of keycodes mapped to a physical keyboard layout, which are processed on key presses and releases + +## Layer +An abstraction used to allow a key to serve multiple purposes. The highest active layer takes precedence. + +## Leader Key +A feature that allows you to tap the leader key followed by a sequence of 1, 2, or 3 keys to activate key presses or other quantum features. + +* [Leader Key Documentation](feature_leader_key.md) + +## LED +Light Emitting Diode, the most common device used for indicators on a keyboard. + +## Make +Software package that is used to compile all the source files. You run `make` with various options to compile your keyboard firmware. + +## Matrix +A wiring pattern of columns and rows that enables the MCU to detect keypresses with a fewer number of pins. The matrix often incorporates diodes to allow for NKRO. + +## Macro +A feature that lets you send multiple keypress events (hid reports) after having pressed only a single key. + +* [Macro Documentation](feature_macros.md) + +## MCU +Microcontrol Unit, the processor that powers your keyboard. + +## Modifier +A key that is held down while typing another key to modify the action of that key. Examples include Ctrl, Alt, and Shift. + +## Mousekeys +A feature that lets you control your mouse cursor and click from your keyboard. + +* [Mousekeys Documentation](feature_mouse_keys.md) + +## N-Key Rollover (NKRO) +A term that applies to keyboards that are capable of reporting any number of key-presses at once. + +## Oneshot Modifier +A modifier that acts as if it is held down until another key is released, so you can press the mod and then press the key, rather than holding the mod while pressing the key. Also known as a Sticky key or a Dead key. + +## ProMicro +A low cost AVR development board. Clones of this device are often found on ebay very inexpensively (under $5) but people often struggle with flashing their pro micros. + +## Pull Request +A request to submit code to QMK. We encourage all users to submit Pull Requests for their personal keymaps. + +## QWERTY +The standard English keyboard layout, and often a shortcut for other language's standard layouts. Named for the first 6 letters on the keyboard. + +## QWERTZ +The standard Deutsche (German) keyboard layout. Named for the first 6 letters on the keyboard. + +## Rollover +The term for pressing a key while a key is already held down. Variants include 2KRO, 6KRO, and NKRO. + +## Scancode +A 1 byte number that is sent as part of a HID report over USB that represents a single key. These numbers are documented in the [HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) published by the [USB-IF](http://www.usb.org/). + +## Space Cadet Shift +A special set of shift keys which allow you to type various types of braces by tapping the left or right shift one or more times. + +* [Space Cadet Shift Documentation](feature_space_cadet_shift.md) + +## Tap +Pressing and releasing a key. In some situations you will need to distinguish between a key down and a key up event, and Tap always refers to both at once. + +## Tap Dance +A feature that lets you assign multiple keycodes to the same key based on how many times you press it. + +* [Tap Dance Documentation](feature_tap_dance.md) + +## Teensy +A low-cost AVR development board that is commonly used for hand-wired builds. A teensy is often chosen despite costing a few dollars more due to its halfkay bootloader, which makes flashing very simple. + +## Underlight +A generic term for LEDs that light the underside of the board. These LEDs typically shine away from the bottom of the PCB and towards the surface the keyboard rests on. + +## Unicode +In the larger computer world Unicode is a set of encoding schemes for representing characters in any language. As it relates to QMK it means using various OS schemes to send unicode codepoints instead of scancodes. + +* [Unicode Documentation](feature_unicode.md) + +## Unit Testing +A framework for running automated tests against QMK. Unit testing helps us be confident that our changes do not break anything. + +* [Unit Testing Documentation](unit_testing.md) + +## USB +Universal Serial Bus, the most common wired interface for a keyboard. + +## USB Host (or simply Host) +The USB Host is your computer, or whatever device your keyboard is plugged into. + +# Couldn't Find the Term You're Looking For? + +[Open an issue](https://github.com/qmk/qmk_firmware/issues) with your question and the term in question could be added here. Better still, open a pull request with the definition. :) diff --git a/reference_info_json.md b/reference_info_json.md new file mode 100644 index 00000000000..3ca62c719e7 --- /dev/null +++ b/reference_info_json.md @@ -0,0 +1,73 @@ +# `info.json` + +This file is used by the [QMK API](https://github.com/qmk/qmk_api). It contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard. You can also set metadata here. + +You can create `info.json` files at every level under `qmk_firmware/keyboards/` to specify this metadata. These files are combined, with more specific files overriding keys in less specific files. This means you do not need to duplicate your metadata information. For example, `qmk_firmware/keyboards/clueboard/info.json` specifies `manufacturer` and `maintainer`, while `qmk_firmware/keyboards/clueboard/66/info.json` specifies more specific information about Clueboard 66%. + +## `info.json` Format + +The `info.json` file is a JSON formatted dictionary with the following keys available to be set. You do not have to set all of them, merely the keys that apply to your keyboard. + +* `keyboard_name` + * A free-form text string describing the keyboard. + * Example: `Clueboard 66%` +* `url` + * A URL to the keyboard's product page, [QMK.fm/keyboards](https://qmk.fm/keyboards) page, or other page describing information about the keyboard. +* `maintainer` + * GitHub username of the maintainer, or `qmk` for community maintained boards +* `width` + * Width of the board in Key Units +* `height` + * Height of the board in Key Units +* `layouts` + * Physical Layout representations. See the next section for more detail. + +### Layout Format + +Within our `info.json` file the `layouts` portion of the dictionary contains several nested dictionaries. The outer layer consists of QMK layout macros, for example `LAYOUT_ansi` or `LAYOUT_iso`. Within each layout macro are keys for `width`, `height`, and `key_count`, each of which should be self-explanatory. + +* `width` + * Optional: The width of the layout in Key Units +* `height` + * Optional: The height of the layout in Key Units +* `key_count` + * Optional: The number of keys in this layout +* `layout` + * A list of Key Dictionaries describing the physical layout. See the next section for more details. + +### Key Dictionary Format + +Each Key Dictionary in a layout describes the physical properties of a key. If you are familiar with the Raw Code for you will find many of the concepts the same. We re-use the same key names and layout choices wherever possible, but unlike keyboard-layout-editor each key is stateless, inheriting no properties from the keys that came before it. + +All key positions and rotations are specified in relation to the top-left corner of the keyboard, and the top-left corner of each key. + +* `x` + * **Required**: The absolute position of the key in the horizontal axis, in Key Units. +* `y` + * **Required**: The absolute position of the key in the vertical axis, in Key Units. +* `w` + * The width of the key, in Key Units. Ignored if `ks` is provided. Default: `1` +* `h` + * The height of the key, in Key Units. Ignored if `ks` is provided. Default: `1` +* `r` + * How many degrees clockwise to rotate the key. +* `rx` + * The absolute position of the point to rotate the key around in the horizontal axis. Default: `x` +* `ry` + * The absolute position of the point to rotate the key around in the vertical axis. Default: `y` +* `ks` + * Key Shape: define a polygon by providing a list of points, in Key Units. + * **Important**: These are relative to the top-left of the key, not absolute. + * Example ISO Enter: `[ [0,0], [1.5,0], [1.5,2], [0.25,2], [0.25,1], [0,1], [0,0] ]` +* `label` + * What to name this position in the matrix. + * This should usually be the same name as what is silkscreened on the PCB at this location. + +## How is the Metadata Exposed? + +This metadata is primarily used in two ways: + +* To allow web-based configurators to dynamically generate UI +* To support the new `make keyboard:keymap:qmk` target, which bundles this metadata up with the firmware to allow QMK Toolbox to be smarter. + +Configurator authors can see the [QMK Compiler](https://docs.api.qmk.fm/using-the-api) docs for more information on using the JSON API. diff --git a/reference_keymap_extras.md b/reference_keymap_extras.md new file mode 100644 index 00000000000..7e3d9bf274f --- /dev/null +++ b/reference_keymap_extras.md @@ -0,0 +1,83 @@ +# Language-specific Keycodes + +Keyboards are able to support a wide range of languages. However, they do not send the actual characters produced by pressing their keys - instead, they send numerical codes. In the USB HID spec, these are called "usages", although they are more often referred to as "scancodes" or "keycodes" when in the context of keyboards. +Less than 256 usages are defined in the HID Keyboard/Keypad usage page, and some of those do nothing on modern operating systems. So, how is this language support achieved? + +In a nutshell, the operating system maps the usages it receives to the appropriate character based on the user's configured keyboard layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`. + +Obviously, this could get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. + +To use these, simply `#include` the corresponding [header file](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras) in your `keymap.c`, and add the keycodes defined in them in place of the `KC_` prefixed ones: + +|Layout |Header | +|---------------------------|--------------------------------| +|Canadian Multilingual (CSA)|`keymap_canadian_multilingual.h`| +|Croatian |`keymap_croatian.h` | +|Czech |`keymap_czech.h` | +|Danish |`keymap_danish.h` | +|Dutch (Belgium) |`keymap_belgian.h` | +|English (Ireland) |`keymap_irish.h` | +|English (UK) |`keymap_uk.h` | +|English (US International) |`keymap_us_international.h` | +|Estonian |`keymap_estonian.h` | +|Finnish |`keymap_finnish.h` | +|French |`keymap_french.h` | +|French (AFNOR) |`keymap_french_afnor.h` | +|French (BÉPO) |`keymap_bepo.h` | +|French (Belgium) |`keymap_belgian.h` | +|French (Switzerland) |`keymap_fr_ch.h` | +|French (macOS, ISO) |`keymap_french_osx.h` | +|German |`keymap_german.h` | +|German (Switzerland) |`keymap_german_ch.h` | +|German (macOS) |`keymap_german_osx.h` | +|German (Neo2)* |`keymap_neo2.h` | +|Greek* |`keymap_greek.h` | +|Hebrew* |`keymap_hebrew.h` | +|Hungarian |`keymap_hungarian.h` | +|Icelandic |`keymap_icelandic.h` | +|Italian |`keymap_italian.h` | +|Italian (macOS, ANSI) |`keymap_italian_osx_ansi.h` | +|Italian (macOS, ISO) |`keymap_italian_osx_iso.h` | +|Japanese |`keymap_jp.h` | +|Korean |`keymap_korean.h` | +|Latvian |`keymap_latvian.h` | +|Lithuanian (ĄŽERTY) |`keymap_lithuanian_azerty.h` | +|Lithuanian (QWERTY) |`keymap_lithuanian_qwerty.h` | +|Norwegian |`keymap_norwegian.h` | +|Polish |`keymap_polish.h` | +|Portuguese |`keymap_portuguese.h` | +|Portuguese (Brazil) |`keymap_br_abnt2.h` | +|Romanian |`keymap_romanian.h` | +|Russian* |`keymap_russian.h` | +|Serbian* |`keymap_serbian.h` | +|Serbian (Latin) |`keymap_serbian_latin.h` | +|Slovak |`keymap_slovak.h` | +|Slovenian |`keymap_slovenian.h` | +|Spanish |`keymap_spanish.h` | +|Spanish (Dvorak) |`keymap_spanish_dvorak.h` | +|Swedish |`keymap_swedish.h` | +|Turkish (F) |`keymap_turkish_f.h` | +|Turkish (Q) |`keymap_turkish_q.h` | + +There are also a few which are not quite language-specific, but useful if you are not using a QWERTY layout: + +|Layout |Header | +|-------------------|------------------------| +|Colemak |`keymap_colemak.h` | +|Dvorak |`keymap_dvorak.h` | +|Dvorak (French) |`keymap_dvorak_fr.h` | +|Dvorak (Programmer)|`keymap_dvp.h` | +|Norman |`keymap_norman.h` | +|Plover* |`keymap_plover.h` | +|Plover (Dvorak)* |`keymap_plover_dvorak.h`| +|Steno* |`keymap_steno.h` | +|Workman |`keymap_workman.h` | +|Workman (ZXCVM) |`keymap_workman_zxcvm.h`| + +## Sendstring Support + +By default, `SEND_STRING()` assumes a US ANSI keyboard layout is set. If you are using a different layout, you can also `#include "sendstring_*.h"` (as above) in your keymap to override the lookup tables used for mapping ASCII characters to keycodes. + +An important thing to note here is that `SEND_STRING()` only operates on [ASCII text](https://en.wikipedia.org/wiki/ASCII#Character_set). This means that you cannot pass it a string containing Unicode characters - this unfortunately includes accented characters that may be present in your desired layout. +Many layouts make certain characters, such as Grave or Tilde, available only as [dead keys](https://en.wikipedia.org/wiki/Dead_key), so you must add a space immediately after it in the string you want to send, to prevent it from potentially combining with the next character. +Certain other layouts have no Sendstring header as they do not use a Latin-derived alphabet (for example Greek and Russian), and thus there is no way to input most of the ASCII character set. These are marked above with a `*`. diff --git a/ru-ru/README.md b/ru-ru/README.md new file mode 100644 index 00000000000..366a76036e4 --- /dev/null +++ b/ru-ru/README.md @@ -0,0 +1,32 @@ +# Quantum Mechanical Keyboard Firmware + +[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## Что такое QMK Firmware? + +QMK (*Quantum Mechanical Keyboard*) — это сообщество, работающее над ПО с открытым исходным кодом, которое разрабатывает QMK Firmware, QMK Toolbox, qmk.fm и эту документацию. QMK Firmware — это прошивка для клавиатур, основанная на [tmk\_keyboard](http://github.com/tmk/tmk_keyboard) с множеством полезных функций для микроконтроллеров Atmel AVR, а именно, для продуктов компаний [OLKB](http://olkb.com), [ErgoDox EZ](http://www.ergodox-ez.com) и [Clueboard](http://clueboard.co/). Она также была портирована на чипы ARM при помощи ChibiOS. Вы можете использовать ее для клавиатуры, собранной вручную или имеющей нестандартную печатную плату. + +## Как скачать + +Если вы собираетесь добавить раскладку, клавиатуру или новые функции в QMK, то самый простой путь реализации — это [сделать форк репозитория на GitHub](https://github.com/qmk/qmk_firmware#fork-destination-box), клонировать ваш репозиторий локально для дальнейшего внесения изменений, сделать пуш изменений, а затем открыть [пулреквест](https://github.com/qmk/qmk_firmware/pulls) из вашего форка. + +Также вы можете либо скачать репозиторий ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), либо клонировать его через git (`git@github.com:qmk/qmk_firmware.git`) или https (`https://github.com/qmk/qmk_firmware.git`). + +## Как скомпилировать + +Перед компиляцией вам необходимо [настроить окружение](ru-ru/getting_started_build_tools.md) разработчика для AVR или/и ARM. После этого используйте команду `make` со следующим синтаксисом, чтобы собрать клавиатуру и раскладку: + + make planck/rev4:default + +Данная команда соберет ревизию `rev4` клавиатуры `planck` с раскладкой `default`. Не все клавиатуры имеют ревизии (они также называются subprojects или folders), в этом случае она может быть опущена: + + make preonic:default + +## Как настроить + +QMK обладает множеством [функций](ru-ru/features.md) для исследования, и [справочная документация](http://docs.qmk.fm) может стать хорошей отправной точкой для знакомства с ними. Большинством функций можно воспользоваться модифицируя [раскладку](ru-ru/keymap.md) и изменяя [коды клавиш](ru-ru/keycodes.md). diff --git a/ru-ru/_summary.md b/ru-ru/_summary.md new file mode 100644 index 00000000000..09273172b6f --- /dev/null +++ b/ru-ru/_summary.md @@ -0,0 +1,124 @@ +* [Complete Newbs Guide](ru-ru/newbs.md) + * [Getting Started](ru-ru/newbs_getting_started.md) + * [Building Your First Firmware](ru-ru/newbs_building_firmware.md) + * [Flashing Firmware](ru-ru/newbs_flashing.md) + * [Testing and Debugging](ru-ru/newbs_testing_debugging.md) + * [Git Best Practices](ru-ru/newbs_best_practices.md) + * [Learning Resources](ru-ru/newbs_learn_more_resources.md) + +* [QMK Basics](ru-ru/README.md) + * [QMK Introduction](ru-ru/getting_started_introduction.md) + * [QMK CLI](ru-ru/cli.md) + * [QMK CLI Config](ru-ru/cli_configuration.md) + * [Contributing to QMK](ru-ru/contributing.md) + * [How to Use GitHub](ru-ru/getting_started_github.md) + * [Getting Help](ru-ru/getting_started_getting_help.md) + +* [Breaking Changes](ru-ru/breaking_changes.md) + * [2019 Aug 30](ru-ru/ChangeLog/20190830.md) + +* [FAQ](ru-ru/faq.md) + * [General FAQ](ru-ru/faq_general.md) + * [Build/Compile QMK](ru-ru/faq_build.md) + * [Debugging/Troubleshooting QMK](ru-ru/faq_debug.md) + * [Keymap](ru-ru/faq_keymap.md) + * [Driver Installation with Zadig](ru-ru/driver_installation_zadig.md) + +* Detailed Guides + * [Install Build Tools](ru-ru/getting_started_build_tools.md) + * [Vagrant Guide](ru-ru/getting_started_vagrant.md) + * [Build/Compile Instructions](ru-ru/getting_started_make_guide.md) + * [Flashing Firmware](ru-ru/flashing.md) + * [Customizing Functionality](ru-ru/custom_quantum_functions.md) + * [Keymap Overview](ru-ru/keymap.md) + +* [Hardware](ru-ru/hardware.md) + * [Compatible Microcontrollers](ru-ru/compatible_microcontrollers.md) + * [AVR Processors](ru-ru/hardware_avr.md) + * [Drivers](ru-ru/hardware_drivers.md) + +* Reference + * [Keyboard Guidelines](ru-ru/hardware_keyboard_guidelines.md) + * [Config Options](ru-ru/config_options.md) + * [Keycodes](ru-ru/keycodes.md) + * [Coding Conventions - C](ru-ru/coding_conventions_c.md) + * [Coding Conventions - Python](ru-ru/coding_conventions_python.md) + * [Documentation Best Practices](ru-ru/documentation_best_practices.md) + * [Documentation Templates](ru-ru/documentation_templates.md) + * [Glossary](ru-ru/reference_glossary.md) + * [Unit Testing](ru-ru/unit_testing.md) + * [Useful Functions](ru-ru/ref_functions.md) + * [Configurator Support](ru-ru/reference_configurator_support.md) + * [info.json Format](ru-ru/reference_info_json.md) + * [Python CLI Development](ru-ru/cli_development.md) + +* [Features](ru-ru/features.md) + * [Basic Keycodes](ru-ru/keycodes_basic.md) + * [US ANSI Shifted Keys](ru-ru/keycodes_us_ansi_shifted.md) + * [Quantum Keycodes](ru-ru/quantum_keycodes.md) + * [Advanced Keycodes](ru-ru/feature_advanced_keycodes.md) + * [Audio](ru-ru/feature_audio.md) + * [Auto Shift](ru-ru/feature_auto_shift.md) + * [Backlight](ru-ru/feature_backlight.md) + * [Bluetooth](ru-ru/feature_bluetooth.md) + * [Bootmagic](ru-ru/feature_bootmagic.md) + * [Combos](ru-ru/feature_combo.md) + * [Command](ru-ru/feature_command.md) + * [Debounce API](ru-ru/feature_debounce_type.md) + * [DIP Switch](ru-ru/feature_dip_switch.md) + * [Dynamic Macros](ru-ru/feature_dynamic_macros.md) + * [Encoders](ru-ru/feature_encoders.md) + * [Grave Escape](ru-ru/feature_grave_esc.md) + * [Haptic Feedback](ru-ru/feature_haptic_feedback.md) + * [HD44780 LCD Controller](ru-ru/feature_hd44780.md) + * [Key Lock](ru-ru/feature_key_lock.md) + * [Layouts](ru-ru/feature_layouts.md) + * [Leader Key](ru-ru/feature_leader_key.md) + * [LED Matrix](ru-ru/feature_led_matrix.md) + * [Macros](ru-ru/feature_macros.md) + * [Mouse Keys](ru-ru/feature_mouse_keys.md) + * [OLED Driver](ru-ru/feature_oled_driver.md) + * [One Shot Keys](ru-ru/one_shot_keys.md) + * [Pointing Device](ru-ru/feature_pointing_device.md) + * [PS/2 Mouse](ru-ru/feature_ps2_mouse.md) + * [RGB Lighting](ru-ru/feature_rgblight.md) + * [RGB Matrix](ru-ru/feature_rgb_matrix.md) + * [Space Cadet](ru-ru/feature_space_cadet.md) + * [Split Keyboard](ru-ru/feature_split_keyboard.md) + * [Stenography](ru-ru/feature_stenography.md) + * [Swap Hands](ru-ru/feature_swap_hands.md) + * [Tap Dance](ru-ru/feature_tap_dance.md) + * [Terminal](ru-ru/feature_terminal.md) + * [Thermal Printer](ru-ru/feature_thermal_printer.md) + * [Unicode](ru-ru/feature_unicode.md) + * [Userspace](ru-ru/feature_userspace.md) + * [Velocikey](ru-ru/feature_velocikey.md) + +* For Makers and Modders + * [Hand Wiring Guide](ru-ru/hand_wire.md) + * [ISP Flashing Guide](ru-ru/isp_flashing_guide.md) + * [ARM Debugging Guide](ru-ru/arm_debugging.md) + * [I2C Driver](ru-ru/i2c_driver.md) + * [SPI Driver](ru-ru/spi_driver.md) + * [WS2812 Driver](ru-ru/ws2812_driver.md) + * [GPIO Controls](ru-ru/internals_gpio_control.md) + * [Proton C Conversion](ru-ru/proton_c_conversion.md) + +* For a Deeper Understanding + * [How Keyboards Work](ru-ru/how_keyboards_work.md) + * [Understanding QMK](ru-ru/understanding_qmk.md) + +* Other Topics + * [Using Eclipse with QMK](ru-ru/other_eclipse.md) + * [Using VSCode with QMK](ru-ru/other_vscode.md) + * [Support](ru-ru/getting_started_getting_help.md) + * [Translating the QMK Docs](ru-ru/translating.md) + +* QMK Internals (In Progress) + * [Defines](ru-ru/internals_defines.md) + * [Input Callback Reg](ru-ru/internals_input_callback_reg.md) + * [Midi Device](ru-ru/internals_midi_device.md) + * [Midi Device Setup Process](ru-ru/internals_midi_device_setup_process.md) + * [Midi Util](ru-ru/internals_midi_util.md) + * [Send Functions](ru-ru/internals_send_functions.md) + * [Sysex Tools](ru-ru/internals_sysex_tools.md) diff --git a/ru-ru/getting_started_build_tools.md b/ru-ru/getting_started_build_tools.md new file mode 100644 index 00000000000..facdf35633f --- /dev/null +++ b/ru-ru/getting_started_build_tools.md @@ -0,0 +1,153 @@ +# Установка инструментов для сборки + +Данная страница описывает процесс установки окружения для сборки QMK. Эти инструкции относятся к процессорам AVR (таким как atmega32u4). + + + +**Примечание:** Если вы здесь впервые, ознакомьтесь с [Руководством для полных новичков](ru-ru/newbs.md). + +Прежде, чем продолжить, убедитесь, что у вас обновлены подмодули (сторонние библиотеки), выполнив `make git-submodule`. + +## Linux + +Чтобы всегда быть уверенными, что у вас установлены последние версии ПО, можно просто выполнить команду `sudo util/qmk_install.sh`. Она должна установить все необходимые зависимости. **Это выполнит `apt-get upgrade`.** + +Вы также можете устанавливать все вручную, но в данной документации список требований может не всегда быть актуальным. + +Текущие требования представлены ниже, но не все они могут быть необходимы, так как зависят от того, что вы делаете. Также стоит отметить, что в некоторых системах не все зависимости доступны в виде пакетов, или они могут называться по-другому. + +``` +build-essential +gcc +unzip +wget +zip +gcc-avr +binutils-avr +avr-libc +dfu-programmer +dfu-util +gcc-arm-none-eabi +binutils-arm-none-eabi +libnewlib-arm-none-eabi +git +``` + +Установите все зависимости при помощи вашего любимого менеджера пакетов. + +Пример для Debian / Ubuntu: + + sudo apt-get update + sudo apt-get install gcc unzip wget zip gcc-avr binutils-avr avr-libc dfu-programmer dfu-util gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi + +Пример для Fedora / Red Hat: + + sudo dnf install gcc unzip wget zip dfu-util dfu-programmer avr-gcc avr-libc binutils-avr32-linux-gnu arm-none-eabi-gcc-cs arm-none-eabi-binutils-cs arm-none-eabi-newlib + +Пример для Arch / Manjaro: + + pacman -S base-devel gcc unzip wget zip avr-gcc avr-binutils avr-libc dfu-util arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib git dfu-programmer dfu-util + +## Nix + +Если вы используете [NixOS](https://nixos.org/), или у вас установлена Nix в Linux или macOS, выполните `nix-shell` из корня репозитория, чтобы настроить окружение для сборки. + +По умолчанию, это скачает компиляторы для AVR и ARM. Если вам не нужны они оба, отключите `avr` или `arm` с помощью аргумента, например: + + nix-shell --arg arm false + +## macOS + +Если вы пользуетесь [Homebrew](https://brew.sh/), вы можете использовать следующие команды: + + brew tap osx-cross/avr + brew tap PX4/homebrew-px4 + brew update + brew install avr-gcc@8 + brew link --force avr-gcc@8 + brew install dfu-programmer + brew install dfu-util + brew install gcc-arm-none-eabi + brew install avrdude + +Данный метод является рекомендуемым. Если у вас нет Homebrew, [установите его!](http://brew.sh/) Он очень сильно пригодится тем, кто работает с командной строкой. Стоит отметить, что часть с `make` и `make install` во время установки `avr-gcc@8` из Homebrew может занимать более 20 минут и сильно нагружать CPU. + +## Windows с MSYS2 (рекомендуется) + +Наилучшим окружение для Windows Vista и всех последующих версий (тестировалось с 7 и 10) является [MSYS2](https://www.msys2.org). + +* Для установки MSYS2, скачайте его и следуйте дальнейшим указаниям отсюда: http://www.msys2.org +* Откройте ``MSYS2 MingGW 64-bit`` ярлык +* Перейдите в свой репозиторий QMK. Например, если он находится в корне вашего диска C: + * `$ cd /c/qmk_firmware` +* Запустите `util/qmk_install.sh` и следуйте подсказкам + +## Windows 10 (устарело) + +Это устаревшие инструкции для Windows 10. Мы рекомендуем использовать [MSYS2, как сказано выше](#windows-с-msys2-рекомендуется). + +### Обновление для дизайнеров (Creators Update) + +Если у вас Windows 10 с Обновлением для дизайнеров или новее, вы можете собрать прошивку и прошить ей напрямую. До Обновления для дизайнеров было возможно только собрать прошивку. Если у вас его еще нет, или вы не уверены, следуйте [этим инструкциям](https://support.microsoft.com/en-us/instantanswers/d4efb316-79f0-1aa1-9ef3-dcada78f3fa0/get-the-windows-10-creators-update). + +### Подсистема Windows для Linux (Windows Subsystem for Linux, WSL) + +В дополнение к Обновлению для дизайнеров вам необходима подсистема Windows для Linux, поэтому установите ее, следуя [иснтрукциям здесь](http://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/). Если у вас уже есть подсистема Windows для Linux из Юбилейного обновления (Anniversary update), рекомендуется ее [обновить](https://betanews.com/2017/04/14/upgrade-windows-subsystem-for-linux/) до 16.04LTS, потому что некоторые клавиатуры не компилируются с набором инструментов из 14.04LTS. Стоит отметить, что вы четко должны понимать, что вы делаете, если выбрали метод `sudo do-release-upgrade`. + +### Git + +Если вы уже клонировали репозиторий в файловую систему Windows, вы можете пропустить данную секцию. + +Вам нужно клонировать репозиторий в файловую систему Windows при помощи обычного Git для Windows, а **не** WSL Git. Так что, если вы ещё не установили Git, [скачайте](https://git-scm.com/download/win) и установите его. Затем [настройте его](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup). Важно указать свой адрес электронной почты и имя пользователя, особенно если вы планируете вносить свой вклад в проект. + +Как только Git будет установлен, откройте командную строку Git Bash и поменяйте директорию на ту, в которую хотите клонировать QMK; обратите внимание, что вы должны использовать косую черту, и что доступ к вашему диску C осуществляется примерно так: `/c/path/to/where/you/want/to/go`. Затем выполните `git clone --recurse-submodules https://github.com/qmk/qmk_firmware`, это создаст новую папку `qmk_firmware` в текущей директории. + +### Установка инструментов (Toolchain) + +Установка инструментов (Toolchain) осуществляется через подсистему Windows для Linux, и процесс полностью автоматизирован. Если вы хотите выполнить установку вручную, то не существует никакой другой инструкции помимо самого скрипта. Однако, вы всегда можете открыть ишью и запросить дополнительную информацию. + +1. Откройте "Bash On Ubuntu On Windows" в меню Пуск. +2. Перейдите в папку, в которую клонирована `qmk_firmware`. Обратите внимание, что пути начинаются с `/mnt/` в WSL, так что вы должны написать, например, `cd /mnt/c/path/to/qmk_firmware`. +3. Запустите `util/wsl_install.sh` и следуйте инструкциям на экране. +4. Закройте окно командной строки Bash, и откройте его снова. +5. Все готово, чтобы скомпилировать прошивку и прошить ей! + +### Несколько важных вещей, которые надо запомнить + +* Вы можете запустить `util/wsl_install.sh` еще раз, чтобы установить все последние обновления. +* Ваш репозиторий QMK должен находиться в файловой системе Windows, поскольку WSL не может запускать выполняемые файлы извне. +* WSL Git **не** совместим с Windows Git, поэтому используйте Windows Git Bash или Windows Git GUI для всех операций с Git. +* Вы можете изменять файлы как внутри WSL, так и просто через Windows. Но обратите внимание, что если вы изменяете makefiles или сценарии командной строки, вы должны убедиться, что используете текстовый редактор, который сохраняет файлы с переводом строки в стиле Unix (Unix line endings). В противном случае компиляция может не работать. + +## Docker + +Если это немного сложновато для вас, Docker может стать готовым решением, которое вы ищите. После установки [Docker CE](https://docs.docker.com/install/#supported-platforms) выполните следующую команду из директории `qmk_firmware`, чтобы собрать клавиатуру/раскладку: + +```bash +util/docker_build.sh keyboard:keymap +# Например: util/docker_build.sh ergodox_ez:steno +``` + +Это скомпилирует указанную клавиатуру/раскладку и создаст для вас `.hex` или `.bin` файл с результатом, готовым к процессу прошивки, в директории QMK. Если опустить `:keymap`, будет использована раскладка `default`. Заметьте, что формат параметров такой же, как и в случае сборки командой `make`. + +Вы также можете запустить скрипт без параметров. Тогда он попросит вас ввести поочередно параметры сборки. Возможно, вам это покажется более удобным: + +```bash +util/docker_build.sh +# Читает параметры из пользовательского ввода (оставьте пустым для значений по умолчанию) +``` + +Также имеется поддержка сборки _и_ прошивки клавиатуры прямо из Docker. Для этого укажите еще один параметр `target`: + +```bash +util/docker_build.sh keyboard:keymap:target +# Например: util/docker_build.sh planck/rev6:default:dfu-util +``` + +Если вы используете Linux, это должно работать прямо из коробки. На Windows и macOS это требует запуска [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/). Ее довольно утомительно настраивать, поэтому мы не рекомендуем это; используйте вместо этого [QMK Toolbox](https://github.com/qmk/qmk_toolbox). + +!> Docker для Windows требует включения [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v). Это означает, что он не работает на версиях Windows без Hyper-V, например, на Windows 7, Windows 8 и **Windows 10 Home**. + +## Vagrant + +Если у вас возникли проблемы при сборке прошивки, вы можете попробовать установить инструмент под названием Vagrant. Он сконфигурирует виртуальный компьютер с такими параметрами, которые подходят для сборки прошивки. У OLKB НЕТ файлов такого виртуально компьютера. Подробности о том, как настроить Vagrant, можно найти в [Руководстве по Vagrant](ru-ru/getting_started_vagrant.md). diff --git a/ru-ru/getting_started_getting_help.md b/ru-ru/getting_started_getting_help.md new file mode 100644 index 00000000000..75be44310e5 --- /dev/null +++ b/ru-ru/getting_started_getting_help.md @@ -0,0 +1,15 @@ +# Получение помощи + +Существует много ресурсов для получения помощи по работе с QMK. + +## Чат в реальном времени + +Вы можете найти разработчиков и пользователей QMK на нашем главном [сервере Discord](https://discord.gg/Uq7gcHh). На сервере есть специальные каналы для разговоров о прошивке, Toolbox, оборудовании и конфигураторе. + +## OLKB Сабреддит + +Официальный форум QMK [/r/olkb](https://reddit.com/r/olkb) на [reddit.com](https://reddit.com). + +## GitHub ишью + +Вы можете открыть [ишью на GitHub](https://github.com/qmk/qmk_firmware/issues). Это особенно удобно, когда ваша проблема потребует длительного обсуждения или отладки. diff --git a/ru-ru/getting_started_github.md b/ru-ru/getting_started_github.md new file mode 100644 index 00000000000..4fd80791f11 --- /dev/null +++ b/ru-ru/getting_started_github.md @@ -0,0 +1,64 @@ +# Как использовать GitHub с QMK + +GitHub может показаться несколько сложным для тех, кто никогда с ним не работал. В данном руководстве будет разобран каждый шаг создания форка, клонирования и отправки пулреквеста в QMK. + +?> В этом руководстве предполагается, что вы в какой-то степени знакомы с работой в командной строке, и в вашей системе установлен git. + +Откройте [страницу QMK на GitHub] (https://github.com/qmk/qmk_firmware), и в правом верхнем углу вы увидите кнопку с надписью "Fork": + +![Fork on GitHub](http://i.imgur.com/8Toomz4.jpg) + +Если вы состоите в какой-либо организации, вам нужно выбрать учетную запись, к которой будет привязан форк. В большинстве случаев это будет личной аккаунт. Как только ваш форк будет завершен (иногда это занимает немного времени), нажмите кнопку "Clone or Download": +![Download from GitHub](http://i.imgur.com/N1NYcSz.jpg) + +И обязательно выберите "HTTPS", затем выделите ссылку и скопируйте ее: + +![HTTPS link](http://i.imgur.com/eGO0ohO.jpg) + +Теперь введите `git clone --recurse-submodules ` в командную строку, а затем вставьте ссылку: + +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +Теперь у вас есть форк QMK на вашем локальном компьютере, и вы можете добавить свою раскладку, скомпилировать ее и прошить ей свою клавиатуру. Как только вы будете довольны своими изменениями, есть возможность добавить, зафиксировать их и сделать коммит в свой форк следующим образом: + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +Ваши изменения теперь существуют в вашем форке на GitHub - если вернуться туда (`https://github.com//qmk_firmware`), вы сможете создать "New Pull Request" нажатием на кнопку: + +![New Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +Здесь вы сможете увидеть, какие именно изменения были внесены, - если все выглядит хорошо, вы можете завершить его, нажав "Create Pull Request": + +![Create Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +После отправки мы можем расспросить вас о ваших изменениях, попросить внести корректировки и в конечном итоге принять их! Спасибо за ваш вклад в QMK :) diff --git a/ru-ru/getting_started_introduction.md b/ru-ru/getting_started_introduction.md new file mode 100644 index 00000000000..ccc44180685 --- /dev/null +++ b/ru-ru/getting_started_introduction.md @@ -0,0 +1,58 @@ +# Введение + +Эта страница пытается объяснить основную информацию, которую вы должны знать, чтобы работать с проектом QMK. Предполагается, что вы знакомы с навигацией в оболочке Unix, но не предполагается, что вы знакомы с C или с компиляцией с использованием make. + +## Базовая структура QMK + +QMK - это форк [Джуна Вако (Jun Wako)](https://github.com/tmk) проекта [tmk_keyboard](https://github.com/tmk/tmk_keyboard). Оригинальный код TMK с изменениями можно найти в папке `tmk_core`. Дополнения QMK к проекту можно найти в папке `quantum`. Проекты клавиатур можно найти в папках `handwired` и `keyboard`. + +### Структура пространства пользователя + +Внутри папки `users` находится каталог для каждого пользователя. Это место для пользователей, куда они могут поместить код, чтобы использовать его с разными клавиатурами. Для получения дополнительной информации обратитесь к документации по [функциям пользовательского пространства](ru-ru/feature_userspace.md). + +### Структура проекта клавиатуры + +Внутри папки `keyboards` есть подпапки `handwired` и есть подкаталоги поставщиков и производителей, для примера, `clueboard` - это каталог для каждого проекта клавиатуры, например, `qmk_firmware/keyboards/clueboard/2x1800`. В нем вы найдете следующую структуру: +* `keymaps/`: Различные раскладки клавиш, которые можно собрать. +* `rules.mk`: Файл, который устанавливает параметры по умолчанию для команды "make". Не редактируйте этот файл напрямую, вместо этого используйте `rules.mk`, относящийся к конкретной раскладке. +* `config.h`: Файл, который устанавливает параметры времени компиляции по умолчанию. Не редактируйте этот файл напрямую, вместо этого используйте `config.h`, относящийся к конкретной раскладке. +* `info.json`: Файл настройки раскладки для QMK Configurator. Посмотрите [Поддержку конфигуратора](ru-ru/reference_configurator_support.md) для дополнительной информации. +* `readme.md`: Краткий обзор клавиатуры. +* `.h`: В этом файле определяется раскладка клавиатуры по матрице переключателей клавиатуры. +* `.c`: В этом файле вы можете найти пользовательский код для клавиатуры. + +Для получения дополнительной информации о структуре проекта обратитесь к [Руководству QMK по клавиатуре](ru-ru/hardware_keyboard_guidelines.md). + +### Структура раскладки клавиатуры + +В каждой папке раскладки клавиатуры могут быть найдены следующие файлы. Обязательным является только файл `keymap.c`, и если остальные файлы не найдены, то будут выбраны параметры по умолчанию. + +* `config.h`: настройки вашей раскладки клавиатуры. +* `keymap.c`: весь код вашей раскладки клавиатуры (обязателен). +* `rules.mk`: активированные функции QMK. +* `readme.md`: описание вашей раскладки клавиш, как ее могут использовать другие, и объяснения функций. Пожалуйста, загрузите изображения на сервис, такой как imgur. + +# Файл `config.h` + +Существует 3 возможных местоположения `config.h`: + +* клавиатура (`/keyboards//config.h`) +* пространство пользователя (`/users//config.h`) +* раскладка клавиш (`/keyboards//keymaps//config.h`) + +Система сборки автоматически загружает файлы конфигурации в указанном выше порядке. Если вы хотите переопределить любую настройку, заданную предыдущим `config.h`, вам сначала нужно будет включить некоторый шаблонный код для настроек, которые вы хотите изменить. + +``` +#pragma once +``` + +Затем, чтобы переопределить настройку из предыдущего файла `config.h`, вы должны сделать `#undef` и `#define` для неё снова. + +Код и настройка шаблона вместе выглядят так: +``` +#pragma once + +// Переопределения производятся здесь! +#undef MY_SETTING +#define MY_SETTING 4 +``` diff --git a/ru-ru/newbs.md b/ru-ru/newbs.md new file mode 100644 index 00000000000..0e7bd6499ca --- /dev/null +++ b/ru-ru/newbs.md @@ -0,0 +1,23 @@ +# Руководство по QMK для полных новичков + +QMK ― это мощная прошивка с открытым исходным кодом для вашей механической клавиатуры. Вы можете использовать QMK для легкой и мощной персонализации своей клавиатуры. Люди с разным уровнем умений, от совсем новичков до крутых программистов, успешно применяли QMK, чтобы персонализировать свои клавиатуры. Данное руководство поможет вам сделать то же самое, независимо от уровня вашего мастерства. + +Не уверены, поддерживает ли ваша клавиатура QMK? Если это механическая клавиатура, которую вы собрали сами, шансы достаточно велики. Мы поддерживаем [большое число любительских клавиатур](https://qmk.fm/keyboards/), поэтому, даже если ваша текущая клавиатура не совместима с QMK, у вас не должно возникнуть проблем с нахождением подходящей для ваших нужд. + +## Обзор + +В данном руководстве 7 основных секций: + +* [Первое знакомство](ru-ru/newbs_getting_started.md) +* [Собираем вашу первую прошивку с помощью командной строки](ru-ru/newbs_building_firmware.md) +* [Собираем вашу первую прошивку с помощью онлайн GUI](ru-ru/newbs_building_firmware_configurator.md) +* [Прошиваем файл прошивки](ru-ru/newbs_flashing.md) +* [Тестируем и отлаживаем](ru-ru/newbs_testing_debugging.md) +* [Лучшие практики по Git](ru-ru/newbs_best_practices.md) +* [Узнайте больше на этих ресурсах](ru-ru/newbs_learn_more_resources.md) + +Данное руководство сосредоточено на помощи тем, кто никогда раньше не компилировал ПО. Приятие решений и рекомендации делаются с учетом именно этого. Существует много альтернативных методов для описанных процедур, и мы поддерживаем большинство из них. Если у вас есть сомнения о том, как выполнить задачу, вы можете [попросить у нас совета](ru-ru/getting_started_getting_help.md). + +## Дополнительные ресурсы + +* [Блог Томаса Баарта (Thomas Baart) об основах QMK](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – Созданный пользователем блог, охватывающий основы использования QMK Firmware с точки зрения нового пользователя. diff --git a/ru-ru/newbs_getting_started.md b/ru-ru/newbs_getting_started.md new file mode 100644 index 00000000000..a301e9adba5 --- /dev/null +++ b/ru-ru/newbs_getting_started.md @@ -0,0 +1,102 @@ +# Введение + +У вашей компьютерной клавиатуры внутри есть процессор, похожий на тот, что внутри вашего компьютера. Этот процессор выполняет программное обеспечение, которое отвечает за обнаружение нажатий клавиш и отсылку сигналов состояния клавиатуры, когда клавиши нажимаются и отпускаются. Роль такого ПО выполняет QMK, детектируя нажатия клавиш и отсылая эту информацию главному компьютеру. Сбор собственной раскладки эквивалентен сборке выполняемой программы для вашей клавиатуры. + +QMK старается дать вам большую силу, оставляя простые вещи легкими и делай сложные — возможными. Вам не надо уметь программировать, чтобы создавать мощные прошивки — вам только надо следовать нескольким простым синтаксическим правилам. + +# Первое знакомство + +Перед тем, как вы сможете собирать раскладки, вам необходимо установить некоторое программное обеспечение и настроить ваше окружение для сборки. Это нужно сделать только один раз, вне зависимости от того, для скольких клавиатур вы планируете компилировать прошивки. + +Если вы предпочитаете графический пользовательский интерфейс, пожалуйста, рассмотрите возможность использования онлайн [QMK Конфигуратора](https://config.qmk.fm). Пожалуйста, обратитесь к [Собираем вашу первую прошивку с помощью онлайн GUI](ru-ru/newbs_building_firmware_configurator.md). + + +## Загрузка ПО + +### Текстовый редактор + +Вам понадобится программа, умеющая редактировать и сохранять **обычные текстовые** файлы. Если вы используете Windows, вы можете делать это Блокнотом, а в Linux вы можете использовать gedit. Обе программы являются простыми, но функциональными редакторами. В macOS остерегайтесь стандартного приложения TextEdit: он не будет сохранять обычные текстовые файлы, пока вы явно не выберите _Make Plain Text_ из меню _Format_. + +Вы также можете скачать и установить отдельный текстовый редактор наподобие [Sublime Text](https://www.sublimetext.com/) или [VS Code](https://code.visualstudio.com/). Возможно, это наилучший вариант независимо от платформы, поскольку эти программы сделаны специально для редактирования кода. + +?> Не уверены, какой выбрать текстовый редактор? Лоуренс Брэдфорд (Laurence Bradford) написал [отличное введение](https://learntocodewith.me/programming/basics/text-editors/) в тему. + +### QMK Toolbox + +QMK Toolbox является дополнительной графической программой для Windows и macOS, которая позволяет вам разрабатывать и отлаживать вашу клавиатуру. Вы, вероятно, посчитаете ее бесценной для легкого процесса прошивки вашей клавиатуры и просмотра отладочных сообщений, которые она отображает. + +[Скачайте последний выпуск здесь.](https://github.com/qmk/qmk_toolbox/releases/latest) + +* Для Windows: `qmk_toolbox.exe` (переносимое приложение) или `qmk_toolbox_install.exe` (установщик) +* Для macOS: `QMK.Toolbox.app.zip` (переносимое приложение) или `QMK.Toolbox.pkg` (установщик) + +## Настройте ваше окружение + +Мы постарались сделать установку QMK максимально легкой. Вам нужно только подготовить ваше Linux или Unix окружение, после этого позвольте QMK установить все остальное. + +?> Если вы никогда раньше не работали с командной строкой Linux/Unix, существует несколько базовых концептов и команд, которые необходимо выучить. Эти ресурсы дадут вам достаточно знаний, чтобы работать с QMK:
+[Обязательные к изучению команды Linux](https://www.guru99.com/must-know-linux-commands.html)
+[Несколько базовых команд Unix](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +Вам нужно будет установить MSYS2 и Git. + +* Следуйте инструкциям по установки на [домашней странице MSYS2](https://www.msys2.org). +* Закройте все открытые терминалы MSYS2 и откройте новый терминал MSYS2 MinGW 64-bit. +* Установите Git, выполнив эту команду: `pacman -S git`. + +### macOS + +Вам нужно будет установить Homebrew. Следуйте инструкциям на [домашней странице Homebrew](https://brew.sh). + +После установки Homebrew продолжите чтение с _Установите QMK_. На этом шаге вам надо будет запустить скрипт, который установит остальные пакеты. + +### Linux + +Вам нужно будет установить Git. Скорее всего, он у вас уже есть, но если нет, одна из следующих команд должна установить его: + +* Debian / Ubuntu / Devuan: `apt-get install git` +* Fedora / Red Hat / CentOS: `yum install git` +* Arch: `pacman -S git` + +?> Docker также является вариантом для всех платформ. [Нажмите сюда для получения подробностей.](ru-ru/getting_started_build_tools.md#docker) + +## Установите QMK + +Как только вы настроили ваше Linux/Unix окружение, вы готовы к загрузке QMK. Мы сделаем это при помощи Git, "клонировав" репозиторий QMK. Откройте Терминал или окно MSYS2 MinGW и оставьте его открытым до конца данного руководства. Выполните эти команды внутри него: + +```shell +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +?> Если вы уже знаете, [как пользоваться GitHub](ru-ru/getting_started_github.md), мы рекомендуем вам вместо этого создать и клонировать свой собственный форк. Если вы не понимаете, что это значит, просто проигнорируйте это сообщение. + +QMK включает в себя скрипт, который поможет вам установить все оставшееся, что вам понадобится. Вы должны запустить его, набрав эту команду: + + util/qmk_install.sh + +## Протестируйте ваше окружение для сборки + +Теперь, когда ваше окружение QMK для сборки настроено, вы можете собрать прошивку для вашей клавиатуры. Начните с попытки собрать раскладку для клавиатуры по умолчанию. У вас должно это получиться с помощью команды в этом формате: + + make :default + +Например, чтобы собрать прошивку для Clueboard 66%, вы введете: + + make clueboard/66/rev3:default + +Когда все закончится, вы должны увидеть большой лог, который заканчивается примерно так: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +# Создаем вашу раскладку + +Теперь вы готовы создать свою персональную раскладку! Для этого перейдите к [Собираем вашу первую прошивку](ru-ru/newbs_building_firmware.md). diff --git a/serial_driver.md b/serial_driver.md new file mode 100644 index 00000000000..bc376b6ddda --- /dev/null +++ b/serial_driver.md @@ -0,0 +1,69 @@ +# 'serial' Driver +This driver powers the [Split Keyboard](feature_split_keyboard.md) feature. + +?> Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards. + +All drivers in this category have the following characteristics: +* Provides data and signaling over a single conductor +* Limited to single master, single slave + +## Supported Driver Types + +| | AVR | ARM | +|-------------------|--------------------|--------------------| +| bit bang | :heavy_check_mark: | :heavy_check_mark: | +| USART Half-duplex | | :heavy_check_mark: | + +## Driver configuration + +### Bitbang +Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk: + +```make +SERIAL_DRIVER = bitbang +``` + +Configure the driver via your config.h: +```c +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 +#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5 + // 0: about 189kbps (Experimental only) + // 1: about 137kbps (default) + // 2: about 75kbps + // 3: about 39kbps + // 4: about 26kbps + // 5: about 20kbps +``` + +#### ARM + +!> The bitbang driver causes connection issues with bitbang WS2812 driver + +Along with the generic options above, you must also turn on the `PAL_USE_CALLBACKS` feature in your halconf.h. + +### USART Half-duplex +Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage is that this provides fast and accurate timings. `SOFT_SERIAL_PIN` for this driver is the configured USART TX pin. **The TX pin must have appropriate pull-up resistors**. To configure it, add this to your rules.mk: + +```make +SERIAL_DRIVER = usart +``` + +Configure the hardware via your config.h: +```c +#define SOFT_SERIAL_PIN B6 // USART TX pin +#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5 + // 0: about 460800 baud + // 1: about 230400 baud (default) + // 2: about 115200 baud + // 3: about 57600 baud + // 4: about 38400 baud + // 5: about 19200 baud +#define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1 +#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 +``` + +You must also enable the ChibiOS `SERIAL` feature: +* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE` +* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU) + +Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral. diff --git a/spi_driver.md b/spi_driver.md new file mode 100644 index 00000000000..1d432432ad1 --- /dev/null +++ b/spi_driver.md @@ -0,0 +1,138 @@ +# SPI Master Driver + +The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs. + +## AVR Configuration + +No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU: + +|MCU |`SS`|`SCK`|`MOSI`|`MISO`| +|---------------|----|-----|------|------| +|ATMega16/32U2/4|`B0`|`B1` |`B2` |`B3` | +|AT90USB64/128 |`B0`|`B1` |`B2` |`B3` | +|ATmega32A |`B4`|`B7` |`B5` |`B6` | +|ATmega328/P |`B2`|`B5` |`B3` |`B4` | + +You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually. +`SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`. + +## ChibiOS/ARM Configuration + +You'll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc. + +To enable SPI, modify your board's `halconf.h` to enable SPI - both `HAL_USE_SPI` and `SPI_USE_WAIT` should be `TRUE`, and `SPI_SELECT_MODE` should be `SPI_SELECT_MODE_PAD`. +Then, modify your board's `mcuconf.h` to enable the SPI peripheral you've chosen -- in the case of using SPI2, modify `STM32_SPI_USE_SPI2` to be `TRUE`. + +As per the AVR configuration, you may select any other standard GPIO as a slave select pin, and can be supplied to `spi_start()`. + +Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. + +`config.h` override | Description | Default Value +----------------------------|---------------------------------------------------------------|-------------- +`#define SPI_DRIVER` | SPI peripheral to use - SPI1 => `SPID1`, SPI2 => `SPID2` etc. | `SPID2` +`#define SPI_SCK_PIN` | The pin to use for the SCK | `B13` +`#define SPI_SCK_PAL_MODE` | The alternate function mode for the SCK pin | `5` +`#define SPI_MOSI_PIN` | The pin to use for the MOSI | `B15` +`#define SPI_MOSI_PAL_MODE` | The alternate function mode for the MOSI pin | `5` +`#define SPI_MISO_PIN` | The pin to use for the MISO | `B14` +`#define SPI_MISO_PAL_MODE` | The alternate function mode for the MISO pin | `5` + +## Functions + +### `void spi_init(void)` + +Initialize the SPI driver. This function must be called only once, before any of the below functions can be called. + +--- + +### `bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)` + +Start an SPI transaction. + +#### Arguments + + - `pin_t slavePin` + The QMK pin to assert as the slave select pin, eg. `B4`. + - `bool lsbFirst` + Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first. + - `uint8_t mode` + The SPI mode to use: + + |Mode|Clock Polarity |Clock Phase | + |----|--------------------|-----------------------| + |`0` |Leading edge rising |Sample on leading edge | + |`1` |Leading edge rising |Sample on trailing edge| + |`2` |Leading edge falling|Sample on leading edge | + |`3` |Leading edge falling|Sample on trailing edge| + + - `uint16_t divisor` + The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`. + +#### Return Value + +`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`. + +--- + +### `spi_status_t spi_write(uint8_t data)` + +Write a byte to the selected SPI device. + +#### Arguments + + - `uint8_t data` + The byte to write. + +#### Return Value + +`SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`. + +--- + +### `spi_status_t spi_read(void)` + +Read a byte from the selected SPI device. + +#### Return Value + +`SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device. + +--- + +### `spi_status_t spi_transmit(const uint8_t *data, uint16_t length)` + +Send multiple bytes to the selected SPI device. + +#### Arguments + + - `const uint8_t *data` + A pointer to the data to write from. + - `uint16_t length` + The number of bytes to write. Take care not to overrun the length of `data`. + +#### Return Value + +`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise. + +--- + +### `spi_status_t spi_receive(uint8_t *data, uint16_t length)` + +Receive multiple bytes from the selected SPI device. + +#### Arguments + + - `uint8_t *data` + A pointer to the buffer to read into. + - `uint16_t length` + The number of bytes to read. Take care not to overrun the length of `data`. + +#### Return Value + +`SPI_STATUS_TIMEOUT` if the internal transmission timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise. + +--- + +### `void spi_stop(void)` + +End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`. diff --git a/support.md b/support.md new file mode 100644 index 00000000000..938d9daf784 --- /dev/null +++ b/support.md @@ -0,0 +1,17 @@ +# Getting Help + +There are a lot of resources for getting help with QMK. + +Please read our [Code of Conduct](https://qmk.fm/coc/) before participating in any of our community spaces. + +## Realtime Chat + +If you need help with something, the best place to get quick support is going to be on our [Discord Server](https://discord.gg/Uq7gcHh). There is usually somebody online, and there are a bunch of very helpful people there. + +## OLKB Subreddit + +The official QMK forum is [/r/olkb](https://reddit.com/r/olkb) on [reddit.com](https://reddit.com). + +## GitHub Issues + +You can open an [issue on GitHub](https://github.com/qmk/qmk_firmware/issues). This is especially handy when your issue will require long-term discussion or debugging. diff --git a/sw.js b/sw.js new file mode 100644 index 00000000000..1e4aaeb7621 --- /dev/null +++ b/sw.js @@ -0,0 +1,83 @@ +/* =========================================================== + * docsify sw.js + * =========================================================== + * Copyright 2016 @huxpro + * Licensed under Apache 2.0 + * Register service worker. + * ========================================================== */ + +const RUNTIME = 'docsify' +const HOSTNAME_WHITELIST = [ + self.location.hostname, + 'fonts.gstatic.com', + 'fonts.googleapis.com', + 'unpkg.com' +] + +// The Util Function to hack URLs of intercepted requests +const getFixedUrl = (req) => { + var now = Date.now() + var url = new URL(req.url) + + // 1. fixed http URL + // Just keep syncing with location.protocol + // fetch(httpURL) belongs to active mixed content. + // And fetch(httpRequest) is not supported yet. + url.protocol = self.location.protocol + + // 2. add query for caching-busting. + // Github Pages served with Cache-Control: max-age=600 + // max-age on mutable content is error-prone, with SW life of bugs can even extend. + // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. + // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 + if (url.hostname === self.location.hostname) { + url.search += (url.search ? '&' : '?') + 'cache-bust=' + now + } + return url.href +} + +/** + * @Lifecycle Activate + * New one activated when old isnt being used. + * + * waitUntil(): activating ====> activated + */ +self.addEventListener('activate', event => { + event.waitUntil(self.clients.claim()) +}) + +/** + * @Functional Fetch + * All network requests are being intercepted here. + * + * void respondWith(Promise r) + */ +self.addEventListener('fetch', event => { + // Skip some of cross-origin requests, like those for Google Analytics. + if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { + // Stale-while-revalidate + // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale + // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 + const cached = caches.match(event.request) + const fixedUrl = getFixedUrl(event.request) + const fetched = fetch(fixedUrl, { cache: 'no-store' }) + const fetchedCopy = fetched.then(resp => resp.clone()) + + // Call respondWith() with whatever we get first. + // If the fetch fails (e.g disconnected), wait for the cache. + // If there’s nothing in cache, wait for the fetch. + // If neither yields a response, return offline pages. + event.respondWith( + Promise.race([fetched.catch(_ => cached), cached]) + .then(resp => resp || fetched) + .catch(_ => { /* eat any errors */ }) + ) + + // Update the cache with the version we fetched (only for ok status) + event.waitUntil( + Promise.all([fetchedCopy, caches.open(RUNTIME)]) + .then(([response, cache]) => response.ok && cache.put(event.request, response)) + .catch(_ => { /* eat any errors */ }) + ) + } +}) diff --git a/syllabus.md b/syllabus.md new file mode 100644 index 00000000000..ec7f66ba780 --- /dev/null +++ b/syllabus.md @@ -0,0 +1,70 @@ +# QMK Syllabus + +This page helps you build up your QMK knowledge by introducing the basics first and guiding you to understanding all the concepts you need to know to be proficient with QMK. + +# Beginning Topics + +If you read nothing else you should read the documents in this section. After reading the [Tutorial](newbs.md) you should be able to create a basic keymap, compile it, and flash it to your keyboard. The remaining documents will flesh out your knowledge of these basics. + +* **Learn How To Use QMK Tools** + * [Tutorial](newbs.md) + * [CLI](cli.md) + * [GIT](newbs_git_best_practices.md) +* **Learn About Keymaps** + * [Layers](feature_layers.md) + * [Keycodes](keycodes.md) + * The full list of keycodes you can use. Note that some may require knowledge found in the Intermediate or Advanced Topics. +* **Configuring IDEs** - Optional + * [Eclipse](other_eclipse.md) + * [VS Code](other_vscode.md) + +# Intermediate Topics + +These topics start to dig into some of the features that QMK supports. You don't have to read all of these documents, but some of the documents in the Advanced Topics section won't make sense if you skip over some of these. + +* **Learn How To Configure Features** + + * [Audio](feature_audio.md) + * Lighting + * [Backlight](feature_backlight.md) + * [LED Matrix](feature_led_matrix.md) + * [RGB Lighting](feature_rgblight.md) + * [RGB Matrix](feature_rgb_matrix.md) + * [Tap-Hold Configuration](tap_hold.md) +* **Learn More About Keymaps** + * [Keymaps](keymap.md) + * [Custom Functions and Keycodes](custom_quantum_functions.md) + * Macros + * [Dynamic Macros](feature_dynamic_macros.md) + * [Compiled Macros](feature_macros.md) + * [Tap Dance](feature_tap_dance.md) + * [Combos](feature_combo.md) + * [Userspace](feature_userspace.md) + +# Advanced Topics + +Everything below here requires a lot of foundational knowledge. Besides being able to create keymaps using advanced features you should be familiar with using both `config.h` and `rules.mk` to configure options for your keyboard. + +* **Maintaining Keyboards Within QMK** + * [Handwiring a Keyboard](hand_wire.md) + * [Keyboard Guidelines](hardware_keyboard_guidelines.md) + * [info.json Reference](reference_info_json.md) + * [Debounce API](feature_debounce_type.md) +* **Advanced Features** + * [Unicode](feature_unicode.md) + * [API](api_overview.md) + * [Bootmagic](feature_bootmagic.md) +* **Hardware** + * [How Keyboards Work](how_keyboards_work.md) + * [How A Keyboard Matrix Works](how_a_matrix_works.md) + * [Split Keyboards](feature_split_keyboard.md) + * [Stenography](feature_stenography.md) + * [Pointing Devices](feature_pointing_device.md) +* **Core Development** + * [Coding Conventions](coding_conventions_c.md) + * [Compatible Microcontrollers](compatible_microcontrollers.md) + * [Custom Matrix](custom_matrix.md) + * [Understanding QMK](understanding_qmk.md) +* **CLI Development** + * [Coding Conventions](coding_conventions_python.md) + * [CLI Development Overview](cli_development.md) diff --git a/tap_hold.md b/tap_hold.md new file mode 100644 index 00000000000..9ffbfde8fc1 --- /dev/null +++ b/tap_hold.md @@ -0,0 +1,190 @@ +# Tap-Hold Configuration Options + +While Tap-Hold options are fantastic, they are not without their issues. We have tried to configure them with reasonable defaults, but that may still cause issues for some people. + +These options let you modify the behavior of the Tap-Hold keys. + +## Tapping Term + +The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. And the exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key. + +You can set the global time for this by adding the following setting to your `config.h`: + +```c +#define TAPPING_TERM 200 +``` + +This setting is defined in milliseconds, and does default to 200ms. This is a good average for a majority of people. + +For more granular control of this feature, you can add the following to your `config.h`: +```c +#define TAPPING_TERM_PER_KEY +``` + +You can then add the following function to your keymap: + +```c +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SFT_T(KC_SPC): + return TAPPING_TERM + 1250; + case LT(1, KC_GRV): + return 130; + default: + return TAPPING_TERM; + } +} +``` + + +## Permissive Hold + +As of [PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/), there is a new `config.h` option: + +```c +#define PERMISSIVE_HOLD +``` + +This makes tap and hold keys (like Mod Tap) work better for fast typists, or for high `TAPPING_TERM` settings. + +If you press a Mod Tap key, tap another key (press and release) and then release the Mod Tap key, all within the tapping term, it will output the tapping function for both keys. + +For Instance: + +- `SFT_T(KC_A)` Down +- `KC_X` Down +- `KC_X` Up +- `SFT_T(KC_A)` Up + +Normally, if you do all this within the `TAPPING_TERM` (default: 200ms) this will be registered as `ax` by the firmware and host system. With permissive hold enabled, this modifies how this is handled by considering the Mod Tap keys as a Mod if another key is tapped, and would registered as `X` (`SHIFT`+`x`). + +?> If you have `Ignore Mod Tap Interrupt` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`. + +For more granular control of this feature, you can add the following to your `config.h`: + +```c +#define PERMISSIVE_HOLD_PER_KEY +``` + +You can then add the following function to your keymap: + +```c +bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LT(1, KC_BSPC): + return true; + default: + return false; + } +} +``` + +## Ignore Mod Tap Interrupt + +To enable this setting, add this to your `config.h`: + +```c +#define IGNORE_MOD_TAP_INTERRUPT +``` + +Similar to Permissive Hold, this alters how the firmware processes inputs for fast typists. If you press a Mod Tap key, press another key, release the Mod Tap key, and then release the normal key, it would normally output the tapping function for both keys. This may not be desirable for rolling combo keys. + +Setting `Ignore Mod Tap Interrupt` requires holding both keys for the `TAPPING_TERM` to trigger the hold function (the mod). + +For Instance: + +- `SFT_T(KC_A)` Down +- `KC_X` Down +- `SFT_T(KC_A)` Up +- `KC_X` Up + +Normally, this would send `X` (`SHIFT`+`x`). With `Ignore Mod Tap Interrupt` enabled, holding both keys are required for the `TAPPING_TERM` to register the hold action. A quick tap will output `ax` in this case, while a hold on both will still output `X` (`SHIFT`+`x`). + + +?> __Note__: This only concerns modifiers and not layer switching keys. + +?> If you have `Permissive Hold` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`. + +For more granular control of this feature, you can add the following to your `config.h`: + +```c +#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +``` + +You can then add the following function to your keymap: + +```c +bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SFT_T(KC_SPC): + return true; + default: + return false; + } +} +``` + +## Tapping Force Hold + +To enable `tapping force hold`, add the following to your `config.h`: + +```c +#define TAPPING_FORCE_HOLD +``` + +When the user holds a key after tapping it, the tapping function is repeated by default, rather than activating the hold function. This allows keeping the ability to auto-repeat the tapping function of a dual-role key. `TAPPING_FORCE_HOLD` removes that ability to let the user activate the hold function instead, in the case of holding the dual-role key after having tapped it. + +Example: + +- `SFT_T(KC_A)` Down +- `SFT_T(KC_A)` Up +- `SFT_T(KC_A)` Down +- wait until the tapping term expires... +- `SFT_T(KC_A)` Up + +With default settings, `a` will be sent on the first release, then `a` will be sent on the second press allowing the computer to trigger its auto repeat function. + +With `TAPPING_FORCE_HOLD`, the second press will be interpreted as a Shift, allowing to use it as a modifier shortly after having used it as a tap. + +!> `TAPPING_FORCE_HOLD` will break anything that uses tapping toggles (Such as the `TT` layer keycode, and the One Shot Tap Toggle). + +For more granular control of this feature, you can add the following to your `config.h`: + +```c +#define TAPPING_FORCE_HOLD_PER_KEY +``` + +You can then add the following function to your keymap: + +```c +bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case LT(1, KC_BSPC): + return true; + default: + return false; + } +} +``` + +## Retro Tapping + +To enable `retro tapping`, add the following to your `config.h`: + +```c +#define RETRO_TAPPING +``` + +Holding and releasing a dual function key without pressing another key will result in nothing happening. With retro tapping enabled, releasing the key without pressing another will send the original keycode even if it is outside the tapping term. + +For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead. + +## Why do we include the key record for the per key functions? + +One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that. + +Well, it's simple really: customization. But specifically, it depends on how your keyboard is wired up. For instance, if each row is actually using a row in the keyboard's matrix, then it may be simpler to use `if (record->event.row == 3)` instead of checking a whole bunch of keycodes. Which is especially good for those people using the Tap Hold type keys on the home row. So you could fine tune those to not interfere with your normal typing. + +## Why is there no `*_kb` or `*_user` functions?! + +Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard level function. Only user level functions are useful here, so no need to mark them as such. diff --git a/translating.md b/translating.md new file mode 100644 index 00000000000..4365817590d --- /dev/null +++ b/translating.md @@ -0,0 +1,55 @@ +# Translating the QMK Docs + +All files in the root folder (`docs/`) should be in English - all other languages should be in subfolders with the ISO 639-1 language codes, followed by `-` and the country code where relevant. [A list of common ones can be found here](https://www.andiamo.co.uk/resources/iso-language-codes/). If this folder doesn't exist, you may create it. Each of the translated files should have the same name as the English version, so things can fall back successfully. + +A `_summary.md` file should exist in this folder with a list of links to each file, with a translated name, and link preceded by the language folder: + +```markdown + * [QMK简介](zh-cn/getting_started_introduction.md) +``` + +All links to other docs pages must also be prefixed with the language folder. If the link is to a specific part of the page (ie. a certain heading), you must use the English ID for the heading, like so: + +```markdown +[建立你的环境](zh-cn/newbs-getting-started.md#set-up-your-environment) + +## 建立你的环境 :id=set-up-your-environment +``` + +Once you've finished translating a new language, you'll also need to modify the following files: + +* [`docs/_langs.md`](https://github.com/qmk/qmk_firmware/blob/master/docs/_langs.md) + Each line should contain a country flag as a [GitHub emoji shortcode](https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#country-flag) followed by the name represented in its own language: + + ```markdown + - [:cn: 中文](/zh-cn/) + ``` + +* [`docs/index.html`](https://github.com/qmk/qmk_firmware/blob/master/docs/index.html) + Both `placeholder` and `noData` objects should have a dictionary entry for the language folder in a string: + + ```js + '/zh-cn/': '没有结果!', + ``` + + The `nameLink` object, for setting the "QMK Firmware" heading link in the sidebar, must also be added to: + + ```js + '/zh-cn/': '/#/zh-cn/', + ``` + + And make sure to add the language folder in the `fallbackLanguages` list, so it will properly fall back to English instead of 404ing: + + ```js + fallbackLanguages: [ + // ... + 'zh-cn', + // ... + ], + ``` + +## Previewing the Translations + +See [Previewing the Documentation](contributing.md#previewing-the-documentation) for how to set up a local instance of the docs - you should be able to select your new language from the "Translations" menu at the top-right. + +Once you're happy with your work, feel free to open a pull request! diff --git a/understanding_qmk.md b/understanding_qmk.md new file mode 100644 index 00000000000..93964242582 --- /dev/null +++ b/understanding_qmk.md @@ -0,0 +1,191 @@ +# Understanding QMK's Code + +This document attempts to explain how the QMK firmware works from a very high level. It assumes you understand basic programming concepts but does not (except where needed to demonstrate) assume familiarity with C. It assumes that you have a basic understanding of the following documents: + +* [Introduction](getting_started_introduction.md) +* [How Keyboards Work](how_keyboards_work.md) +* [FAQ](faq.md) + +## Startup + +You can think of QMK as no different from any other computer program. It is started, performs its tasks, and then ends. The entry point for the program is the `main()` function, just like it is on any other C program. However, for a newcomer to QMK it can be confusing because the `main()` function appears in multiple places, and it can be hard to tell which one to look at. + +The reason for this is the different platforms that QMK supports. The most common platform is `lufa`, which runs on AVR processors such at the atmega32u4. We also support `chibios` and `vusb`. + +We'll focus on AVR processors for the moment, which use the `lufa` platform. You can find the `main()` function in [tmk_core/protocol/lufa/lufa.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1028). If you browse through that function you'll find that it initializes any hardware that has been configured (including USB to the host) and then it starts the core part of the program with a [`while(1)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1069). This is [The Main Loop](#the-main-loop). + +## The Main Loop + +This section of code is called "The Main Loop" because it's responsible for looping over the same set of instructions forever. This is where QMK dispatches out to the functions responsible for making the keyboard do everything it is supposed to do. At first glance it can look like a lot of functionality but most of the time the code will be disabled by `#define`'s. + +``` + keyboard_task(); +``` + +This is where all the keyboard specific functionality is dispatched. The source code for `keyboard_task()` can be found in [tmk_core/common/keyboard.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/keyboard.c#L216), and it is responsible for detecting changes in the matrix and turning status LEDs on and off. + +Within `keyboard_task()` you'll find code to handle: + +* [Matrix Scanning](#matrix-scanning) +* Mouse Handling +* Serial Link(s) +* Visualizer +* Keyboard status LEDs (Caps Lock, Num Lock, Scroll Lock) + +#### Matrix Scanning + +Matrix scanning is the core function of a keyboard firmware. It is the process of detecting which keys are currently pressed, and your keyboard runs this function many times a second. It's no exaggeration to say that 99% of your firmware's CPU time is spent on matrix scanning. + +While there are different strategies for doing the actual matrix detection, they are out of scope for this document. It is sufficient to treat matrix scanning as a black box, you ask for the matrix's current state and get back a datastructure that looks like this: + + +``` +{ + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +That datastructure is a direct representation of the matrix for a 4 row by 5 column numpad. When a key is pressed that key's position within the matrix will be returned as `1` instead of `0`. + +Matrix Scanning runs many times per second. The exact rate varies but typically it runs at least 10 times per second to avoid perceptible lag. + +##### Matrix to Physical Layout Map + +Once we know the state of every switch on our keyboard we have to map that to a keycode. In QMK this is done by making use of C macros to allow us to separate the definition of the physical layout from the definition of keycodes. + +At the keyboard level we define a C macro (typically named `LAYOUT()`) which maps our keyboard's matrix to physical keys. Sometimes the matrix does not have a switch in every location, and we can use this macro to pre-populate those with KC_NO, making the keymap definition easier to work with. Here's an example `LAYOUT()` macro for a numpad: + +```c +#define LAYOUT( \ + k00, k01, k02, k03, \ + k10, k11, k12, k13, \ + k20, k21, k22, \ + k30, k31, k32, k33, \ + k40, k42 \ +) { \ + { k00, k01, k02, k03, }, \ + { k10, k11, k12, k13, }, \ + { k20, k21, k22, KC_NO, }, \ + { k30, k31, k32, k33, }, \ + { k40, KC_NO, k42, KC_NO } \ +} +``` + +Notice how the second block of our `LAYOUT()` macro matches the Matrix Scanning array above? This macro is what will map the matrix scanning array to keycodes. However, if you look at a 17 key numpad you'll notice that it has 3 places where the matrix could have a switch but doesn't, due to larger keys. We have populated those spaces with `KC_NO` so that our keymap definition doesn't have to. + +You can also use this macro to handle unusual matrix layouts, for example the [Clueboard rev 2](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/66/rev2/rev2.h). Explaining that is outside the scope of this document. + +##### Keycode Assignment + +At the keymap level we make use of our `LAYOUT()` macro above to map keycodes to physical locations to matrix locations. It looks like this: + +``` +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT( + KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \ + KC_P7, KC_P8, KC_P9, KC_PPLS, \ + KC_P4, KC_P5, KC_P6, \ + KC_P1, KC_P2, KC_P3, KC_PENT, \ + KC_P0, KC_PDOT) +} +``` + +Notice how all of these arguments match up with the first half of the `LAYOUT()` macro from the last section? This is how we take a keycode and map it to our Matrix Scan from earlier. + +##### State Change Detection + +The matrix scanning described above tells us the state of the matrix at a given moment, but your computer only wants to know about changes, it doesn't care about the current state. QMK stores the results from the last matrix scan and compares the results from this matrix to determine when a key has been pressed or released. + +Let's look at an example. We'll hop into the middle of a keyboard scanning loop to find that our previous scan looks like this: + +``` +{ + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +And when our current scan completes it will look like this: + +``` +{ + {1,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0} +} +``` + +Comparing against our keymap we can see that the pressed key is KC_NLCK. From here we dispatch to the `process_record` set of functions. + + + +##### Process Record + +The `process_record()` function itself is deceptively simple, but hidden within is a gateway to overriding functionality at various levels of QMK. The chain of events is listed below, using cluecard whenever we need to look at the keyboard/keymap level functions. Depending on options set in `rules.mk` or elsewhere, only a subset of the functions below will be included in final firmware. + +* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/action.c#L172) + * [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L206) + * [Map this record to a keycode](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L226) + * [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/c1c5922aae7b60b7c7d13d3769350eed9dda17ab/quantum/velocikey.c#L27) + * [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L119) + * [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_key_lock.c#L62) + * [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_clicky.c#L79) + * [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/2cee371bf125a6ec541dd7c5a809573facc7c456/drivers/haptic/haptic.c#L216) + * [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/card.c#L20) + * [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/keymaps/default/keymap.c#L58) + * [`bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/rgb_matrix.c#L139) + * [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_midi.c#L81) + * [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_audio.c#L19) + * [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_steno.c#L160) + * [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_music.c#L114) + * [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L141) + * [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode_common.c#L169) + calls one of: + * [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode.c#L20) + * [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46) + * [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95) + * [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51) + * [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115) + * [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77) + * [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94) + * [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264) + * [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291) + +At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing. + +After this is called, `post_process_record()` is called, which can be used to handle additional cleanup that needs to be run after the keycode is normally handled. + +* [`void post_process_record(keyrecord_t *record)`]() + * [`void post_process_record_quantum(keyrecord_t *record)`]() + * [Map this record to a keycode]() + * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]() + * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]() + * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]() + + diff --git a/unit_testing.md b/unit_testing.md new file mode 100644 index 00000000000..a63ffff5d37 --- /dev/null +++ b/unit_testing.md @@ -0,0 +1,68 @@ +# Unit Testing + +If you are new to unit testing, then you can find many good resources on internet. However most of it is scattered around in small pieces here and there, and there's also many different opinions, so I won't give any recommendations. + +Instead I recommend these two books, explaining two different styles of Unit Testing in detail. + +* "Test Driven Development: By Example: Kent Beck" +* "Growing Object-Oriented Software, Guided By Tests: Steve Freeman, Nat Pryce" + +If you prefer videos there are Uncle Bob's [Clean Coders Videos](https://cleancoders.com/), which unfortunately cost quite a bit, especially if you want to watch many of them. But James Shore has a free [Let's Play](http://www.jamesshore.com/Blog/Lets-Play) video series. + +## Google Test and Google Mock +It's possible to Unit Test your code using [Google Test](https://github.com/google/googletest). The Google Test framework also includes another component for writing testing mocks and stubs, called "Google Mock". For information how to write the actual tests, please refer to the documentation on that site. + +## Use of C++ + +Note that Google Test and therefore any test has to be written in C++, even if the rest of the QMK codebases is written in C. This should hopefully not be a problem even if you don't know any C++, since there's quite clear documentation and examples of the required C++ features, and you can write the rest of the test code almost as you would write normal C. Note that some compiler errors which you might get can look quite scary, but just read carefully what it says, and you should be ok. + +One thing to remember, is that you have to append `extern "C"` around all of your C file includes. + +## Adding Tests for New or Existing Features + +If you want to unit test some feature, then take a look at the existing serial_link tests, in the `quantum/serial_link/tests folder`, and follow the steps below to create a similar structure. + +1. If it doesn't already exist, add a test subfolder to the folder containing the feature. +2. Create a `testlist.mk` and a `rules.mk` file in that folder. +3. Include those files from the root folder `testlist.mk`and `build_test.mk` respectively. +4. Add a new name for your testgroup to the `testlist.mk` file. Each group defined there will be a separate executable. And that's how you can support mocking out different parts. Note that it's worth adding some common prefix, just like it's done for the serial_link tests. The reason for that is that the make command allows substring filtering, so this way you can easily run a subset of the tests. +5. Define the source files and required options in the `rules.mk` file. + * `_SRC` for source files + * `_DEFS` for additional defines + * `_INC` for additional include folders +6. Write the tests in a new cpp file inside the test folder you created. That file has to be one of the files included from the `rules.mk` file. + +Note how there's several different tests, each mocking out a separate part. Also note that each of them only compiles the very minimum that's needed for the tests. It's recommend that you try to do the same. For a relevant video check out [Matt Hargett "Advanced Unit Testing in C & C++](https://www.youtube.com/watch?v=Wmy6g-aVgZI) + +## Running the Tests + +To run all the tests in the codebase, type `make test`. You can also run test matching a substring by typing `make test:matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer. + +## Debugging the Tests + +If there are problems with the tests, you can find the executable in the `./build/test` folder. You should be able to run those with GDB or a similar debugger. + +## Full Integration Tests + +It's not yet possible to do a full integration test, where you would compile the whole firmware and define a keymap that you are going to test. However there are plans for doing that, because writing tests that way would probably be easier, at least for people that are not used to unit testing. + +In that model you would emulate the input, and expect a certain output from the emulated keyboard. + +# Tracing Variables :id=tracing-variables + +Sometimes you might wonder why a variable gets changed and where, and this can be quite tricky to track down without having a debugger. It's of course possible to manually add print statements to track it, but you can also enable the variable trace feature. This works for both variables that are changed by the code, and when the variable is changed by some memory corruption. + +To take the feature into use add `VARIABLE_TRACE=x` to the end of you make command. `x` represents the number of variables you want to trace, which is usually 1. + +Then at a suitable place in the code, call `ADD_TRACED_VARIABLE`, to begin the tracing. For example to trace all the layer changes, you can do this +```c +void matrix_init_user(void) { + ADD_TRACED_VARIABLE("layer", &layer_state, sizeof(layer_state)); +} +``` + +This will add a traced variable named "layer" (the name is just for your information), which tracks the memory location of `layer_state`. It tracks 4 bytes (the size of `layer_state`), so any modification to the variable will be reported. By default you can not specify a size bigger than 4, but you can change it by adding `MAX_VARIABLE_TRACE_SIZE=x` to the end of the make command line. + +In order to actually detect changes to the variables you should call `VERIFY_TRACED_VARIABLES` around the code that you think that modifies the variable. If a variable is modified it will tell you between which two `VERIFY_TRACED_VARIABLES` calls the modification happened. You can then add more calls to track it down further. I don't recommend spamming the codebase with calls. It's better to start with a few, and then keep adding them in a binary search fashion. You can also delete the ones you don't need, as each call need to store the file name and line number in the ROM, so you can run out of memory if you add too many calls. + +Also remember to delete all the tracing code once you have found the bug, as you wouldn't want to create a pull request with tracing code. diff --git a/usb_nkro.txt b/usb_nkro.txt new file mode 100644 index 00000000000..d9f1d122921 --- /dev/null +++ b/usb_nkro.txt @@ -0,0 +1,160 @@ +USB NKRO MEMO +============= +2010/12/09 + + +References +---------- +USB - boot mode, NKRO, compatibility, etc... + http://geekhack.org/showthread.php?t=13162 +NKey Rollover - Overview, Testing Methodology, and Results + http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results +dfj's NKRO(2010/06) + http://geekhack.org/showpost.php?p=191195&postcount=251 + http://geekhack.org/showthread.php?p=204389#post204389 + + +Terminology +--------- +NKRO +ghost +matrix +mechanical with diodes +membrane + + +OS Support Status +----------------- +USB NKRO is possible *without* a custom driver. +At least following OS's supports. + Windows7 64bit + WindowsXP + Windows2000 SP4 + Ubuntu10.4(Linux 2.6) + MacOSX(To be tested) + + +Custom Driver for USB NKRO +-------------------------- +NOT NEEDED +at least when using following report formats on Windows, Linux or MacOSX. + + +USB NKRO methods +---------------- +1. Virtual keyboards + Keyboard can increase its KRO by using virtual keyboards with Standard or Extended report. + If the keyboard has 2 virtual keyboard with Standard report(6KRO), it gets 12KRO. + Using this method means the keyboard is a composite device. + +2. Extended report + It needs large report size for this method to achieve NKRO. + If a keyboard has 101keys, it needs 103byte report. It seems to be inefficient. + +3. Bitmap report + If the keyboard has less than 128keys, 16byte report will be enough for NKRO. + The 16byte report seems to be reasonable cost to get NKRO. + + +Report Format +------------- +Other report formats than followings are possible, though these format are typical one. + +1. Standard 8bytes + modifiers(bitmap) 1byte + reserved 1byte(not used) + keys(array) 1byte*6 +Standard report can send 6keys plus 8modifiers simultaneously. +Standard report is used by most keyboards in the marketplace. +Standard report is identical to boot protocol report. +Standard report is hard to suffer from compatibility problems. + +2. Extended standard 16,32,64bytes + modifiers(bitmap) 1byte + reserved 1byte(not used) + keys(array) 1byte*(14,32,62) +Extended report can send N-keys by using N+2bytes. +Extended report is expected to be compatible with boot protocol. + +3. Bitmap 16,32,64bytes + keys(bitmap) (16,32)bytes +Bitmap report can send at most 128keys by 16bytes and 256keys by 32bytes. +Bitmap report can achieve USB NKRO efficiently in terms of report size. +Bitmap report needs a deliberation for boot protocol implementation. +Bitmap report descriptor sample: + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application), + // bitmap of modifiers + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte + // LED output report + 0x95, 0x05, // Report Count (5), + 0x75, 0x01, // Report Size (1), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), + 0x95, 0x01, // Report Count (1), + 0x75, 0x03, // Report Size (3), + 0x91, 0x03, // Output (Constant), + // bitmap of keys + 0x95, (REPORT_BYTES-1)*8, // Report Count (), + 0x75, 0x01, // Report Size (1), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum(1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, (REPORT_BYTES-1)*8-1, // Usage Maximum (), + 0x81, 0x02, // Input (Data, Variable, Absolute), + 0xc0 // End Collection +where REPORT_BYTES is a report size in bytes. + + +Considerations +-------------- +Compatibility + boot protocol + minor/old system + Some BIOS doesn't send SET_PROTOCOL request, a keyboard can't switch to boot protocol mode. + This may cause a problem on a keyboard which uses other report than Standard. +Reactivity + USB polling time + OS/Driver processing time + + +Windows Problem +--------------- +1. Windows accepts only 6keys in case of Standard report. + It should be able to send 6keys plus 8modifiers. +2. Windows accepts only 10keys in case of 16bytes Extended report. + It should be able to send 14keys plus 8modifiers. +3. Windows accepts only 18keys in case of 32bytes Extended report. + It should be able to send 30keys plus 8modifiers. +If keys are pressed in excess of the number, wrong keys are registered on Windows. + +This problem will be reportedly fixed soon.(2010/12/05) + http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 + + +Tools for testing NKRO +---------------------- +Browser App: +http://www.microsoft.com/appliedsciences/content/projects/KeyboardGhostingDemo.aspx +http://random.xem.us/rollover.html + +Windows: +AquaKeyTest.exe http://geekhack.org/showthread.php?t=6643 + +Linux: +xkeycaps +xev +showkeys + +EOF diff --git a/ws2812_driver.md b/ws2812_driver.md new file mode 100644 index 00000000000..c1b96329e9c --- /dev/null +++ b/ws2812_driver.md @@ -0,0 +1,122 @@ +# WS2812 Driver +This driver powers the [RGB Lighting](feature_rgblight.md) and [RGB Matrix](feature_rgb_matrix.md) features. + +Currently QMK supports the following addressable LEDs (however, the white LED in RGBW variants is not supported): + + WS2811, WS2812, WS2812B, WS2812C, etc. + SK6812, SK6812MINI, SK6805 + +These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs. + +## Supported Driver Types + +| | AVR | ARM | +|----------|--------------------|--------------------| +| bit bang | :heavy_check_mark: | :heavy_check_mark: | +| I2C | :heavy_check_mark: | | +| SPI | | :heavy_check_mark: | +| PWM | | :heavy_check_mark: | + +## Driver configuration + +### All drivers + +Different versions of the addressable LEDs have differing requirements for the TRST period between frames. +The default setting is 280 µs, which should work for most cases, but this can be overridden in your config.h. e.g.: + +```c +#define WS2812_TRST_US 80 +``` + +### Bitbang +Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk: + +```make +WS2812_DRIVER = bitbang +``` + +!> This driver is not hardware accelerated and may not be performant on heavily loaded systems. + +### I2C +Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk: + +```make +WS2812_DRIVER = i2c +``` + +Configure the hardware via your config.h: +```c +#define WS2812_ADDRESS 0xb0 // default: 0xb0 +#define WS2812_TIMEOUT 100 // default: 100 +``` + +### SPI +Targeting STM32 boards where WS2812 support is offloaded to an SPI hardware device. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. `RGB_DI_PIN` for this driver is the configured SPI MOSI pin. Due to the nature of repurposing SPI to drive the LEDs, the other SPI pins, MISO and SCK, **must** remain unused. To configure it, add this to your rules.mk: + +```make +WS2812_DRIVER = spi +``` + +Configure the hardware via your config.h: +```c +#define WS2812_SPI SPID1 // default: SPID1 +#define WS2812_SPI_MOSI_PAL_MODE 5 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5 +``` + +You must also turn on the SPI feature in your halconf.h and mcuconf.h + +#### Testing Notes + +While not an exhaustive list, the following table provides the scenarios that have been partially validated: + +| | SPI1 | SPI2 | SPI3 | +|-|-|-|-| +| f072 | ? | B15 :heavy_check_mark: | N/A | +| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A | +| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: | + +*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* + +### PWM + +Targeting STM32 boards where WS2812 support is offloaded to an PWM timer and DMA stream. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. To configure it, add this to your rules.mk: + +```make +WS2812_DRIVER = pwm +``` + +Configure the hardware via your config.h: +```c +#define WS2812_PWM_DRIVER PWMD2 // default: PWMD2 +#define WS2812_PWM_CHANNEL 2 // default: 2 +#define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2 +#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. +#define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. +#define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM2_UP // DMAMUX configuration for TIMx_UP -- only required if your MCU has a DMAMUX peripheral, see the respective reference manual for the appropriate values for your MCU. +``` + +You must also turn on the PWM feature in your halconf.h and mcuconf.h + +#### Testing Notes + +While not an exhaustive list, the following table provides the scenarios that have been partially validated: + +| | Status | +|-|-| +| f072 | ? | +| f103 | :heavy_check_mark: | +| f303 | :heavy_check_mark: | +| f401/f411 | :heavy_check_mark: | + +*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* + +### Push Pull and Open Drain Configuration +The default configuration is a push pull on the defined pin. +This can be configured for bitbang, PWM and SPI. + +Note: This only applies to STM32 boards. + + To configure the `RGB_DI_PIN` to open drain configuration add this to your config.h file: +```c +#define WS2812_EXTERNAL_PULLUP +``` diff --git a/zh-cn/README.md b/zh-cn/README.md new file mode 100644 index 00000000000..173af882dab --- /dev/null +++ b/zh-cn/README.md @@ -0,0 +1,32 @@ +# QMK机械键盘固件 + +[![当前版本](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) +[![开发状态](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) +[![异议](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) +[![文档状态](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) +[![GitHub贡献者](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) +[![GitHub分支](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) + +## 什么是 QMK 固件? + +QMK (*Quantum Mechanical Keyboard*) 是一个社区维护的开源软件,包括 QMK 固件, QMK 工具箱, qmk.fm网站, 和这些文档。QMK 固件是一个基于[tmk\_keyboard](http://github.com/tmk/tmk_keyboard)的键盘固件,它在爱特梅尔AVR微控制器实现一些有用的功能,确切地说, 是在 [OLKB product line](http://olkb.com), 在 [ErgoDox EZ](http://www.ergodox-ez.com) 键盘, 和 [Clueboard product line](http://clueboard.co/). 上。它被移植到使用ChibiOS的ARM芯片上. 它可以在飞线键盘或定制PCB键盘中发挥功能. + +## 如何得到它 + +如果你打算贡献布局, 键盘, 或者其他QMK特性, 一下是最简单的方法:[从GitHub获得repo分支](https://github.com/qmk/qmk_firmware#fork-destination-box), 并克隆你的repo到本地进行编辑,推送,然后从你的分支打开 [Pull Request](https://github.com/qmk/qmk_firmware/pulls). + +此外, 你也可以直接下载 ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), 或者从git克隆 (`git@github.com:qmk/qmk_firmware.git`), 或 https (`https://github.com/qmk/qmk_firmware.git`). + +## 如何编译 + +在你能编译之前, 你需要[部署环境](zh-cn/getting_started_build_tools.md) 用于 AVR or/and ARM 开发。完成后, 你可以使用 `make` 命令来编译一个键盘和布局使用以下命令: + + make planck/rev4:default + +这将建立 `planck`的`rev4` 修订版本并使用 `default`布局。并非所有键盘都有修订版本 (也叫做子项目或文件夹),在此情况下,修订版本可以省略,如下: + + make preonic:default + +## 如何定制 + +QMK 有许多 [特性](zh-cn/features.md)来探索,也有很多 [参考文档](http://docs.qmk.fm) 供您发掘。你可以通过修改 [布局](zh-cn/keymap.md)和[键码](zh-cn/keycodes.md)来利用许多特性。 diff --git a/zh-cn/_summary.md b/zh-cn/_summary.md new file mode 100644 index 00000000000..cedcfbd5257 --- /dev/null +++ b/zh-cn/_summary.md @@ -0,0 +1,133 @@ +* [完全菜鸟指南](zh-cn/newbs.md) + * [入门](zh-cn/newbs_getting_started.md) + * [构建你的第一个固件](zh-cn/newbs_building_firmware.md) + * [刷新固件](zh-cn/newbs_flashing.md) + * [测试和调试](zh-cn/newbs_testing_debugging.md) + * [Git最佳实践](zh-cn/newbs_git_best_practices.md) + * [使用你分叉(fork)的主分支(master)](zh-cn/newbs_git_using_your_master_branch.md) + * [解决合并冲突](zh-cn/newbs_git_resolving_merge_conflicts.md) + * [重新同步一个分支](zh-cn/newbs_git_resynchronize_a_branch.md) + * [学习资源](zh-cn/newbs_learn_more_resources.md) + +* [QMK基础](zh-cn/README.md) + * [QMK简介](zh-cn/getting_started_introduction.md) + * [QMK命令行工具](zh-cn/cli.md) + * [QMK命令行工具配置](zh-cn/cli_configuration.md) + * [向QMK贡献代码](zh-cn/contributing.md) + * [如何使用GitHub](zh-cn/getting_started_github.md) + * [获得帮助](zh-cn/getting_started_getting_help.md) + +* [非兼容性修改](zh-cn/breaking_changes.md) + * [我的PR已经被标记为非兼容性修改](zh-cn/breaking_changes_instructions.md) + * [2019年8月30日](zh-cn/ChangeLog/20190830.md) + +* [问题与解答](zh-cn/faq.md) + * [一般问题](zh-cn/faq_general.md) + * [构建/编译](zh-cn/faq_build.md) + * [调试/故障排除](zh-cn/faq_debug.md) + * [布局](zh-cn/faq_keymap.md) + * [Zadig驱动安装](zh-cn/driver_installation_zadig.md) + +* 详细指南 + * [安装构建工具](zh-cn/getting_started_build_tools.md) + * [vagrant指南](zh-cn/getting_started_vagrant.md) + * [构建/编译指南](zh-cn/getting_started_make_guide.md) + * [刷新固件](zh-cn/flashing.md) + * [定制功能](zh-cn/custom_quantum_functions.md) + * [布局概述](zh-cn/keymap.md) + +* [硬件](zh-cn/hardware.md) + * [兼容的单片机](zh-cn/compatible_microcontrollers.md) + * [AVR处理器](zh-cn/hardware_avr.md) + * [驱动](zh-cn/hardware_drivers.md) + +* 参考 + * [键盘指南](zh-cn/hardware_keyboard_guidelines.md) + * [配置选项](zh-cn/config_options.md) + * [键码](zh-cn/keycodes.md) + * [代码书写规范 - C](zh-cn/coding_conventions_c.md) + * [代码书写规范 - Python](zh-cn/coding_conventions_python.md) + * [文档书写规范](zh-cn/documentation_best_practices.md) + * [文档模板](zh-cn/documentation_templates.md) + * [术语表](zh-cn/reference_glossary.md) + * [单元测试](zh-cn/unit_testing.md) + * [实用函数](zh-cn/ref_functions.md) + * [配置器支持](zh-cn/reference_configurator_support.md) + * [info.json 格式](zh-cn/reference_info_json.md) + * [Python 命令行开发](zh-cn/cli_development.md) + +* [特性](zh-cn/features.md) + * [基本键码](zh-cn/keycodes_basic.md) + * [US ANSI控制码](zh-cn/keycodes_us_ansi_shifted.md) + * [量子键码](zh-cn/quantum_keycodes.md) + * [高级键码](zh-cn/feature_advanced_keycodes.md) + * [音频](zh-cn/feature_audio.md) + * [自动shift](zh-cn/feature_auto_shift.md) + * [背光](zh-cn/feature_backlight.md) + * [蓝牙](zh-cn/feature_bluetooth.md) + * [热改键](zh-cn/feature_bootmagic.md) + * [组合](zh-cn/feature_combo) + * [命令](zh-cn/feature_command.md) + * [消抖 API](zh-cn/feature_debounce_type.md) + * [拨动开关](zh-cn/feature_dip_switch.md) + * [动态宏指令](zh-cn/feature_dynamic_macros.md) + * [编码器](zh-cn/feature_encoders.md) + * [重音号Esc复合键](zh-cn/feature_grave_esc.md) + * [触摸反馈](zh-cn/feature_haptic_feedback.md) + * [HD44780 LCD控制器](zh-cn/feature_hd44780.md) + * [自锁键](zh-cn/feature_key_lock.md) + * [布局](zh-cn/feature_layouts.md) + * [前导键](zh-cn/feature_leader_key.md) + * [LED阵列](zh-cn/feature_led_matrix.md) + * [宏指令](zh-cn/feature_macros.md) + * [鼠标键](zh-cn/feature_mouse_keys.md) + * [OLED驱动](zh-cn/feature_oled_driver.md) + * [一键功能](zh-cn/one_shot_keys.md) + * [指针设备](zh-cn/feature_pointing_device.md) + * [PS/2鼠标](zh-cn/feature_ps2_mouse.md) + * [RGB灯光](zh-cn/feature_rgblight.md) + * [RGB矩阵](zh-cn/feature_rgb_matrix.md) + * [空格候补换挡](zh-cn/feature_space_cadet.md) + * [分体键盘](zh-cn/feature_split_keyboard.md) + * [速录机](zh-cn/feature_stenography.md) + * [换手](zh-cn/feature_swap_hands.md) + * [多击键](zh-cn/feature_tap_dance.md) + * [终端](zh-cn/feature_terminal.md) + * [热敏打印机](zh-cn/feature_thermal_printer.md) + * [Unicode](zh-cn/feature_unicode.md) + * [用户空间](zh-cn/feature_userspace.md) + * [速度键](zh-cn/feature_velocikey.md) + +* 制造和定制者指南 + * [手工连线指南](zh-cn/hand_wire.md) + * [ISP刷新指南](zh-cn/isp_flashing_guide.md) + * [ARM调试指南](zh-cn/arm_debugging.md) + * [ADC设备](zh-cn/adc_driver.md) + * [I2C设备](zh-cn/i2c_driver.md) + * [SPI设备](zh-cn/spi_driver.md) + * [WS2812设备](zh-cn/ws2812_driver.md) + * [EEPROM设备](zh-cn/eeprom_driver.md) + * [GPIO控制](zh-cn/internals_gpio_control.md) + * [自定义键盘矩阵](zh-cn/custom_matrix.md) + * [Proton C转换](zh-cn/proton_c_conversion.md) + +* 深入了解 + * [键盘工作原理](zh-cn/how_keyboards_work.md) + * [深入了解QMK](zh-cn/understanding_qmk.md) + +* 其他话题 + * [使用Eclipse开发QMK](zh-cn/other_eclipse.md) + * [使用VSCode开发QMK](zh-cn/other_vscode.md) + * [支持](zh-cn/getting_started_getting_help.md) + * [翻译QMK文档](zh-cn/translating.md) + +* QMK 内构 (正在编写) + * [定义](zh-cn/internals_defines.md) + * [输入回调寄存器](zh-cn/internals_input_callback_reg.md) + * [Midi设备](zh-cn/internals_midi_device.md) + * [Midi设备配置过程](zh-cn/internals_midi_device_setup_process.md) + * [Midi工具库](zh-cn/internals_midi_util.md) + * [发送函数](zh-cn/internals_send_functions.md) + * [Sysex工具](zh-cn/internals_sysex_tools.md) + + diff --git a/zh-cn/contributing.md b/zh-cn/contributing.md new file mode 100644 index 00000000000..62b956b619f --- /dev/null +++ b/zh-cn/contributing.md @@ -0,0 +1,205 @@ +# 如何做贡献 + +👍🎉 首先感谢各位百忙之中抽空阅读本文档,并为我们无私奉献。给您点赞啦! 🎉👍 + +第三方的帮助让Q酱成长了许多呢,Q酱也从你们那学到了不少新东西。Q酱希望每一个想帮助我的人都能很方便的做出有用的贡献。在这里我给摩拳擦掌的你们写了一点引导,让你们的代码在不对我做重大改动的情况下都能成功的被采纳哦。 + +* [项目概况](#项目概况) +* [代码规范](#代码规范) +* [一般教程](#一般教程) +* [行为守则对于我来说有何意义?](#行为守则对于我来说有何意义?) + +## 这文章巨长无比不想读啊! 我就想问个问题而已! + +您要是想问关于Q酱的问题的话可以在[OLKB Subreddit](https://reddit.com/r/olkb)或者是[Discord](https://discord.gg/Uq7gcHh)随意问。 + +请记住: + +* 维护Q酱的小可爱有的时候可能会有点忙,不能及时回答您的问题,耐心等等,他们都是很nice的人呀。 +* 维护Q酱的人都是很无私的善良的人。无论是贡献代码还是回答问题,都是义务的。有时见到他们努力回答各种问题,解决各种BUG,Q酱也是很心疼的。 +* 您可以看看下面的教程,可以让您的问题浅显易懂,更容易回答: + * https://opensource.com/life/16/10/how-ask-technical-questions + * http://www.catb.org/esr/faqs/smart-questions.html + +# 项目概况 + +Q酱很大一部分是用C语言组成的,不过有一小部分特性是C++的。怎么说呢,都是我的一部分,两个我都爱。Q酱一般是在键盘上的嵌入式处理器那里工作的,尤其与AVR([LUFA](http://www.fourwalledcubicle.com/LUFA.php))和ARM ([ChibiOS](http://www.chibios.com))两小哥哥搭配,干活不累,嘻嘻。如果您精通Arduino的话您会发现很多熟悉的概念,但也有点不爽,因为您以前的经验可能没法用来帮助Q酱。 + + + +# Q酱,我在哪能帮助你嘞? + +您要是有问题的话可以 [提出一个issue](https://github.com/qmk/qmk_firmware/issues) 或 [在Discord上交流一下](https://discord.gg/Uq7gcHh). + +# Q酱,我如何帮助你? + +您以前是否没为开源贡献过代码,而又想知道帮助Q酱是怎么一回事? 稍安勿躁,咱给您总结一下! + +0. 先注册一个 [GitHub](https://github.com) 账户。 +1. 做好一个你要贡献的布局,那就要 [找一个你想解决的问题](https://github.com/qmk/qmk_firmware/issues),或者 [找一个你想添加的特性](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)。 +2. 把关联着问题的仓库分叉(fork)到你的仓库。这样你在`你的GitHub用户名/qmk_firmware`就有一个仓库备份啦。 +3. 使用 `git clone https://github.com/此处添GitHub用户名/此处添仓库名.git`这个命令把仓库同步到你的电脑中。 +4. 您要是想开发一个新特性的话可以先创建一个issue和Q酱的维护者讨论一下您要做什么。 +5. 使用`git checkout -b 此处写分支名字(别用汉字)`命令来创建一个分支(branch)用于开发。 +6. 对要解决的问题或要添加的特性进行适当的更改。 +7. 使用 `git add 把改变的文件的目录写这里` 可以添加改变的文件内容到git用于管理工程状态的索引(快照)里。 +8. 使用 `git commit -m "这里写修改的相关信息"` 来描述你做出了什么修改。 +9. 使用 `git push origin 此处写分支名字`来把你的更改同步到GitHub库里(反正不是打篮球那个库里)。 +10. 提交一个[QMK 固件的pull request](https://github.com/qmk/qmk_firmware/pull/new/master)。 +11. 给你的pull request拟一个标题,包括简短的描述和问题或错误代码。比如, 你可以起一个这样的"Added more log outputting to resolve #4352"(最好用英语,毕竟Q酱的中文也不是那么的溜,有可能会看不懂中文)。 +12. 在描述(description)里面写你做了哪些更改,你的代码里还存在什么问题, 或者你想问维护的小可爱们的问题。你的your pull request有点小问题无伤大雅(本来也没有完美的代码嘛), 维护的小可爱们会竭尽全力帮您改进的! +13. 维护人员审查代码可能需要一些时间。 +14. 维护人员会通知您要更改什么地方,然后您就按照建议改一改。 +15. 预祝您合并成功! + +# 代码规范 + +其实也没有什么特别严格的规范啦,但是俗话说的好:没有规矩,不成方圆。您可以看一下您的要改动的代码周围的画风,然后保持队形。如果你感觉周围都不知道是什么牛鬼蛇神的话就看看下面的建议: + +* 我们用肆(4)个空格来缩进(软件中也可以设置到Tab键) +* 我们使用改良的1TBS(允许单行样式) + * 左大括号: 在开放性语句块那行的末尾 + * 右大括号: 和开放性语句块第一个字母对齐 + * Else If: 将右大括号放在行的开头,下一个左大括号放在同一行的结尾 + * 可选大括号: 可选大括号是必选的 + * 应该这样: if (condition) { return false; } + * 不应该这样: if (condition) return false; +* 建议使用C语言风格的注释: `/* */` + * 把注释想象成一个描述特征的故事 + * 充分使用注释来描述你为何这样修改 + * 有些公认的东西就不要写到注释里面了 + * 如果你不知道注释是否多余,看下面 +* 一般不要主动换行,主动换行的话每行不要超过76列 +* 要把 `#pragma once` 放到头文件的开始哦,抛弃老土的(`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`)吧 +* 下面两种预处理命令都可以用: `#ifdef DEFINED` 还有 `#if defined(DEFINED)` + * 以上那句对处女座不是很友好哈,处女座的朋友们就别纠结了,直接 `#if defined(DEFINED)` 。 + * 还有就是选好一种风格就一直用,一直用一直爽,不要朝三暮四, 除非你要变化到多重条件的 `#if`。 + * `#` 和 `if`要挨在一起哦,再让本空格在中间冒充电灯泡本空格会生气的。 + * 以下是缩进规则: + * 首先考虑可读性,强迫症的朋友们总想要保持代码的高一致性,这样可不好。 + * 保证文件已有风格不变。如果代码本来就是杂糅风格,那就见机行事,让你的修改更有意义些。 + * 其实你也可以在缩进的时候看看周围其他代码,然后范水模山,预处理命令可以有自己的缩进风格。 + +可以参照下面: + +```c +/* foo 的 Enums*/ +enum foo_state { + FOO_BAR, + FOO_BAZ, +}; + +/* 有返回值的情况 */ +int foo(void) { + if (some_condition) { + return FOO_BAR; + } else { + return -1; + } +} +``` + +# Clang-format的自动格式化 +[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) 是LLVM的一部分,可以帮你自动格式化代码。我们给你准备好了一个适用于以上规范的配置文件,会帮你调整缩进和换行,你只需要写好括号就好。有了它,你再也不用担心调整代码格式太耗时,没有时间陪伴自己(虚构)的另一半了。 + +使用[LLVM 完整安装](http://llvm.org/builds/)可以在Windows上安装clang-format, Ubuntu用户要用`sudo apt install clang-format`。 + +命令行的朋友们, 加上 `-style=file`选项就会自动在QMK的根目录寻找.clang-format配置文件了。 + +VSCode用户, 标准的 C/C++ 插件就支持clang-format, 或者可以用[独立扩展](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat)也行。 + +有些东西(比如LAYOUT宏) 会被clang-format打乱,所以那些文件就别用clang-format了,这里就教您一个小窍门,在`// clang-format off` 和 `//clang-format on`之间装上会被搞乱的代码就好了。 + +# 一般教程 + +你可以给Q酱的不同部分添砖加瓦,但也要用不同的方法严谨检查。不论你修改哪里最好还是看看下边。 + +* 将PR(pull request)分成一个个的逻辑单元。 比如,不要一次将两个新特性PR出去。要添加的特性排好队,一个一个来。 +* 提交之前看一眼,`git diff --check`的空格一定要写对了 +* 确定你的代码能通过编译 + * 布局: 确定`make keyboard:your_new_keymap` 不返回错误 + * 键盘: 确定 `make keyboard:all` 不返回错误 + * 核心代码: 确定 `make all` 不返回错误 +* 提交的信息尽量明确。第一行写点简短介绍(每行不多于70个英文字母), 第二行空着,第三行和后面就要写些必要的细节了。最好用英文写,比如: + +``` +Adjust the fronzlebop for the kerpleplork + +The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations. + +Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure. +``` + +## 文档 + +想帮助Q酱当然是先看文档最简单了。找到这个文档哪里错了然后改正它对于你来说超级简单! 我们也对有写文档能力的人求贤若渴,如果你是对的人[点这个](#Q酱,我在哪能帮助你嘞?)! + +文档呢,都静静的放在`qmk_firmware/docs` 目录里, 也或者您想为网页做贡献的话也是可以的哦。 + +在文档中附代码案例时, 先观察文档其他地方的命名规范。比如, 把enums的名字都改成像`my_layers`或者`my_keycodes`来防止名字不一致的enums被当作特务枪毙: + +```c +enum my_layers { + _FIRST_LAYER, + _SECOND_LAYER +}; + +enum my_keycodes { + FIRST_LAYER = SAFE_RANGE, + SECOND_LAYER +}; +``` + +## 布局 + +大多数QMK新手都从创建一个自己的布局开始。我们尽力保证布局规范宽松 (毕竟布局是个性的体现) 不过建议遵守以下准则,这样可以让别人更好理解你的代码 + +* 用 [模板](documentation_templates.md)写个`readme.md`。 +* 所有的布局PR都会被squash, 如果你想知道你的提交是怎么被squash的那你就自己来吧 +* 不要把新特性和布局一起PR。可以分别PR他们 +* 布局文件夹就不要放`Makefile`了,这个操作都过时啦 +* 更新文件头部的copyrights(看`%YOUR_NAME%`那) + +## 键盘 + +QMK的最终归宿是键盘。有些键盘是社区维护的,有一些是制作这些键盘的人维护的。`readme.md`会告诉你是谁维护了这个键盘,如果你对某个键盘有疑问,可以 [创建一个Issue](https://github.com/qmk/qmk_firmware/issues) 来问一问维护者。 + +我们建议你按下面的来操作: + +* 用[模板](documentation_templates.md)写`readme.md`。 +* 提交数量尽量合理,不然我们可就要把你的PR给squash了。 +* 不要把新特性和新键盘一起PR。可以分别PR他们 +* 用父文件夹的名字命名 `.c`/`.h`文件, 比如`/keyboards///.[ch]` +* 键盘文件夹就不要放`Makefile`了,这个操作都过时啦 +* 更新文件头部的copyrights(看`%YOUR_NAME%`那) + +## Quantum/TMK 核心 + +在您废寝忘食地开发Q酱新特性或者帮Q酱驱虫之前,一定要确保你的工作是有意义的。看看[了解QMK](understanding_qmk.md)你会对Q酱有更深的了解,这个文档将带你领略QMK的程序流程。现在你应该和维护团对谈谈来了解实现你想法的最佳方法了。一下渠道都可以: + +* [在Discord交流](https://discord.gg/Uq7gcHh) +* [建立一个Issue](https://github.com/qmk/qmk_firmware/issues/new) + +新特性和BUG的修复影响所有键盘。开发组也在翻修QMK。所以,在实施重大返修之前一定要讨论一下。如果你在没有事先与维护团队沟通的情况下提交了一个PR,而且你的选择与维护团队的计划方向不符,那你可能要面临大改了。 + +修复BUG或者开发新特性之前看看这个: + +* **默认不启用** - QMK运行的芯片多数内存有限,所以首要考虑的还应该是布局不要被破坏,于是特性默认是不启用的。你喜欢什么特性的话就打开它,如果你觉得有些特性应该默认开启或者你能帮助缩减代码,那就联系维护组吧。 +* **提交之前在本地编译** - 这个简直就是家喻户晓了,但是也确实需要编译啊! 我们的Travis系统会发现一切问题,但是自己编译一下可要比在线等快多了。 +* **注意版本和芯片平台** - 有那么几个键盘有支持不同配置甚至是不同芯片的版本。试着写一个能AVR和ARM两个平台运行的特性,或者在不支持的平台自动禁用。 +* **解释你的新特性** - 在`docs/`写个文档, 你可以创建新文档或者写到现有文档中。如果你不把它记录下来,其他人就无法从你的努力中获益。 + +也可以看看以下建议: + +* 提交数量尽量合理,不然我们可就要把你的PR给squash了。 +* 不要把新特性、布局和键盘一起PR。可以分别PR他们。 +* 给你的特性写[单元测试](unit_testing.md)。 +* 你编辑的文件风格要一致,如果风格不明确或者是混搭风的,你就要先看看[代码规范](#代码规范)确认情况。 + +## 重构 + +为了保持QMK脉络清晰,Q酱打算深入规划重构一下自己,然后让合作者进行修改。如果你有重构的思路或建议[创建一个issue](https://github.com/qmk/qmk_firmware/issues), Q酱很乐意讨论一下怎么改进一下。 + +# 行为守则对于我来说有何意义? + +我们的[行为守则](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md) 是说明您有责任尊重和礼貌地对待项目中的每个人,无论他们的身份如何。 如果你是我们行为准则所描述的不当行为的受害者,我们将站在你这边,并按照行为准则对施暴者进行适当谴责。 diff --git a/zh-cn/custom_quantum_functions.md b/zh-cn/custom_quantum_functions.md new file mode 100644 index 00000000000..27b2edf38f9 --- /dev/null +++ b/zh-cn/custom_quantum_functions.md @@ -0,0 +1,490 @@ +# 如何定制你键盘的功能 + +对于很多人来说客制化键盘可不只是向你的电脑发送你按了那个件这么简单。你肯定想实现比简单按键和宏更复杂的功能。QMK有能让你注入代码的钩子, 覆盖功能, 另外,还可以自定义键盘在不同情况下的行为。 + +本页不假定任何特殊的QMK知识,但阅读[理解QMK](understanding_qmk.md)将会在更基础的层面帮你理解发生了什么。 + +## A Word on Core vs 键盘 vs 布局 + +我们把qmk组织成一个层次结构: + +* Core (`_quantum`) + * Keyboard/Revision (`_kb`) + * Keymap (`_user`) + +下面描述的每一个函数都可以在定义上加一个`_kb()`或 `_user()` 后缀。 建议在键盘/修订层使用`_kb()`后缀,在布局层使用`_user()`后缀。 + +在键盘/修订层定义函数时,`_kb()`在执行任何代码前先调用`_user()`是必要的,不然布局层函数就不要被调用。 + +# 自定义键码 + +到目前为止,最常见的任务是更改现有键码的行为或创建新的键码。从代码角度来看这些操作都很相似。 + +## 定义一个新键码 + +创建键码第一步,先枚举出它全部,也就是给键码起个名字并分配唯一数值。QMK没有直接限制最大键码值大小,而是提供了一个`SAFE_RANGE`宏。你可以在枚举时用`SAFE_RANGE`来保证你取得了唯一的键码值。 + + +这有枚举两个键码的例子。把这块加到`keymap.c`的话你就在布局中能用`FOO`和`BAR`了。 + +```c +enum my_keycodes { + FOO = SAFE_RANGE, + BAR +}; +``` + +## 为键码的行为编程 + +当你覆盖一个已存在按键的行为时,或将这个行为赋给新键时,你要用`process_record_kb()`和`process_record_user()`函数。这俩函数在键处理中真实键事件被处理前被QMK调用。如果这俩函数返回`true`,QMK将会用正常的方式处理键码。这样可以很方便的扩展键码的功能而不是替换它。如果函数返回`false` QMK会跳过正常键处理,然后发送键子抬起还是按下事件就由你决定了。 + +当某个键按下或释放时这俩函数会被调用。 + +### process_record_user()`函数示例实现 + +这个例子做了两个事。自定义了一个叫做`FOO`的键码的行为,并补充了在按下回车时播放音符。 + +```c +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // 按下时做些什么 + } else { + // 释放时做些什么 + } + return false; // 跳过此键的所有进一步处理 + case KC_ENTER: + // 当按下回车时播放音符 + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // 让QMK触发回车按下/释放事件 + default: + return true; // 正常处理其他键码 + } +} +``` + +### `process_record_*` 函数文档 + +* 键盘/修订: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` +* 布局: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` + +`keycode(键码)`参数是在布局上定义的,比如`MO(1)`, `KC_L`, 等等。 你要用 `switch...case` 块来处理这些事件。 + +`record`参数含有实际按键的信息: + +```c +keyrecord_t record { + keyevent_t event { + keypos_t key { + uint8_t col + uint8_t row + } + bool pressed + uint16_t time + } +} +``` + +# LED控制 + +qmk提供了读取HID规范包含的5个LED的方法。: + +* `USB_LED_NUM_LOCK` +* `USB_LED_CAPS_LOCK` +* `USB_LED_SCROLL_LOCK` +* `USB_LED_COMPOSE` +* `USB_LED_KANA` + +这五个常量对应于主机LED状态的位置位。 +有两种方法可以获得主机LED状态: + +* 通过执行 `led_set_user()` +* 通过调用 `host_keyboard_leds()` + +## `led_set_user()` + +当5个LED中任何一个的状态需要改变时,此函数将被调用。此函数通过参数输入LED参数。 +使用`IS_LED_ON(usb_led, led_name)`和`IS_LED_OFF(usb_led, led_name)`这两个宏来检查LED状态。 + +!> `host_keyboard_leds()`可能会在`led_set_user()`被调用前返回新值。 + +### `led_set_user()`函数示例实现 + +```c +void led_set_user(uint8_t usb_led) { + if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) { + writePinLow(B0); + } else { + writePinHigh(B0); + } + if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) { + writePinLow(B1); + } else { + writePinHigh(B1); + } + if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) { + writePinLow(B2); + } else { + writePinHigh(B2); + } + if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) { + writePinLow(B3); + } else { + writePinHigh(B3); + } + if (IS_LED_ON(usb_led, USB_LED_KANA)) { + writePinLow(B4); + } else { + writePinHigh(B4); + } +} +``` + +### `led_set_*`函数文档 + +* 键盘/修订: `void led_set_kb(uint8_t usb_led)` +* 布局: `void led_set_user(uint8_t usb_led)` + +## `host_keyboard_leds()` + +调用这个函数会返回最后收到的LED状态。这个函数在`led_set_*`之外读取LED状态时很有用,比如在[`matrix_scan_user()`](#矩阵扫描代码). +为了便捷,你可以用`IS_HOST_LED_ON(led_name)`和`IS_HOST_LED_OFF(led_name)` 宏,而不直接调用和检查`host_keyboard_leds()`。 + +## 设置物理LED状态 + +一些键盘实现了为设置物理LED的状态提供了方便的方法。 + +### Ergodox Boards + +Ergodox实现了提供`ergodox_right_led_1`/`2`/`3_on`/`off()`来让每个LED开或关, 也可以用 `ergodox_right_led_on`/`off(uint8_t led)` 按索引打开或关闭他们。 + +此外,还可以使用`ergodox_led_all_set(uint8_t n)`指定所有LED的亮度级别;针对每个LED用`ergodox_right_led_1`/`2`/`3_set(uint8_t n)`;使用索引的话用`ergodox_right_led_set(uint8_t led, uint8_t n)`。 + +Ergodox boards 同时定义了最低亮度级别`LED_BRIGHTNESS_LO`和最高亮度级别`LED_BRIGHTNESS_HI`(默认最高). + +# 键盘初始化代码 + +键盘初始化过程有几个步骤。你是用那个函数取决于你想要做什么。 + +有三个主要初始化函数,按调用顺序列出。 + +* `keyboard_pre_init_*` - 会在大多数其他东西运行前运行。适用于哪些需要提前运行的硬件初始化。 +* `matrix_init_*` - 在固件启动过程中间被调用。此时硬件已初始化,功能尚未初始化。 +* `keyboard_post_init_*` - 在固件启动过程最后被调用。大多数情况下,你的“客制化”代码都可以放在这里。 + +!> 对于大多数人来说`keyboard_post_init_user`是你想要调用的函数。例如, 此时你可以设置RGB灯发光。 + +## 键盘预初始化代码 + +这代码极早运行,甚至都在USB初始化前运行。 + +在这之后不久矩阵就被初始化了。 + +对于大多数用户来说,这用不到,因为它主要是用于面向硬件的初始化。 + +但如果你有硬件初始化的话放在这里再好不过了(比如初始化LED引脚一类的). + +### `keyboard_pre_init_user()`函数示例实现 + +本例中在键盘级别,设定 B0, B1, B2, B3, 和 B4 是LED引脚。 + +```c +void keyboard_pre_init_user(void) { + // 调用键盘预初始化代码 + + // 设置LED引脚为输出模式 + setPinOutput(B0); + setPinOutput(B1); + setPinOutput(B2); + setPinOutput(B3); + setPinOutput(B4); +} +``` + +### `keyboard_pre_init_*` 函数文档 + +* 键盘/修订: `void keyboard_pre_init_kb(void)` +* 布局: `void keyboard_pre_init_user(void)` + +## 矩阵初始化代码 + +这将会在矩阵初始化时被调用,在某些硬件设置好后,但在一些功能被初始化前。 + +这在你设置其他地方会用到的东西的时候会很有用,但与硬件无关,也不依赖于它的启动位置。 + + +### `matrix_init_*`函数文档 + +* 键盘/修订: `void matrix_init_kb(void)` +* 布局: `void matrix_init_user(void)` + + +## 键盘后初始化代码 + +这是键盘初始化过程中的最后一个任务。如果您想更改某些特性,这会很有用,因为此时应该对它们进行初始化。 + + +### `keyboard_post_init_user()`示例实现 + +本示例在所有初始化完成后运行,配置RGB灯。 + +```c +void keyboard_post_init_user(void) { + // 调用后初始化代码 + rgblight_enable_noeeprom(); // 使能Rgb,不保存设置 + rgblight_sethsv_noeeprom(180, 255, 255); // 将颜色设置到蓝绿色(青色)不保存 + rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // 设置快速呼吸模式不保存 +} +``` + +### `keyboard_post_init_*` 函数文档 + +* 键盘/修订: `void keyboard_post_init_kb(void)` +* 布局: `void keyboard_post_init_user(void)` + +# 矩阵扫描代码 + +可能的话你要用`process_record_*()`自定义键盘,以这种方式连接到事件中,以确保代码不会对键盘产生负面的性能影响。然而,在极少数情况下,有必要进行矩阵扫描。在这些函数中要特别注意代码的性能,因为它每秒至少被调用10次。 + +### `matrix_scan_*`示例实现 + +这个例子被故意省略了。在hook这样一个对性能及其敏感的区域之前,您应该足够了解qmk的内部结构,以便在没有示例的情况下编写。如果你需要帮助,请[建立一个issue](https://github.com/qmk/qmk_firmware/issues/new)或[在Discord上与我们交流](https://discord.gg/Uq7gcHh). + +### `matrix_scan_*` 函数文档 + +* 键盘/修订: `void matrix_scan_kb(void)` +* 布局: `void matrix_scan_user(void)` + +该函数在每次矩阵扫描时被调用,这基本与MCU处理能力上限相同。在这里写代码要谨慎,因为它会运行很多次。 + +你会在自定义矩阵扫描代码时用到这个函数。这也可以用作自定义状态输出(比如LED灯或者屏幕)或者其他即便用户不输入你也想定期运行的功能。 + + +# 键盘 空闲/唤醒 代码 + +如果键盘支持就可以通过停止一大票功能来达到"空闲"。RGB灯和背光就是很好的例子。这可以节约能耗,也可能让你键盘风味更佳。 + +用两个函数控制: `suspend_power_down_*`和`suspend_wakeup_init_*`, 分别在系统板空闲和唤醒时调用。 + + +### suspend_power_down_user()和suspend_wakeup_init_user()示例实现 + + +```c +void suspend_power_down_user(void) { + rgb_matrix_set_suspend_state(true); +} + +void suspend_wakeup_init_user(void) { + rgb_matrix_set_suspend_state(false); +} +``` + +### 键盘 挂起/唤醒 函数文档 + +* 键盘/修订: `void suspend_power_down_kb(void)` 和`void suspend_wakeup_init_user(void)` +* 布局: `void suspend_power_down_kb(void)` 和 `void suspend_wakeup_init_user(void)` + +# 层改变代码 + +每当层改变这个就运行代码。这对于层指示或自定义层处理很有用。 + +### `layer_state_set_*` 示例实现 + +本例使用了Planck键盘示范了如何设置 [RGB背光灯](feature_rgblight.md)使之与层对应 + +```c +uint32_t layer_state_set_user(uint32_t state) { + switch (biton32(state)) { + case _RAISE: + rgblight_setrgb (0x00, 0x00, 0xFF); + break; + case _LOWER: + rgblight_setrgb (0xFF, 0x00, 0x00); + break; + case _PLOVER: + rgblight_setrgb (0x00, 0xFF, 0x00); + break; + case _ADJUST: + rgblight_setrgb (0x7A, 0x00, 0xFF); + break; + default: // for any other layers, or the default layer + rgblight_setrgb (0x00, 0xFF, 0xFF); + break; + } + return state; +} +``` +### `layer_state_set_*` 函数文档 + +* 键盘/修订: `uint32_t layer_state_set_kb(uint32_t state)` +* 布局: `uint32_t layer_state_set_user(uint32_t state)` + + +该`状态`是活动层的bitmask, 详见[布局概述](keymap.md#布局的层状态) + + +# 掉电保存配置 (EEPROM) + +这会让你的配置长期的保存在键盘中。这些配置保存在你主控的EEPROM里,掉电不会消失。 设置可以用`eeconfig_read_kb`和`eeconfig_read_user`读取,可以用`eeconfig_update_kb`和`eeconfig_update_user`写入。这对于您希望能够切换的功能很有用(比如切换RGB层指示。此外,你可以用`eeconfig_init_kb`和`eeconfig_init_user`来设置EEPROM默认值。 + +最复杂的部分可能是,有很多方法可以通过EEPROM存储和访问数据,并且并没有用哪种方法是“政治正确”的。你每个功能只有一个双字(四字节)空间。 + +记住EEPROM是有写入寿命的。尽管写入寿命很高,但是并不是只有设置写道EEPROM中。如果你写入频繁,你的MCU寿命将会变短。 + +* 如果您不理解这个例子,那么您可能希望避免使用这个特性,因为它相当复杂。 + +### 示例实现 + +本例讲解了如何添加设置,并且读写。本里使用了用户布局。这是一个复杂的函数,有很多事情要做。实际上,它使用了很多上述函数来工作! + + +在你的keymap.c文件中,将以下代码添加至顶部: +```c +typedef union { + uint32_t raw; + struct { + bool rgb_layer_change :1; + }; +} user_config_t; + +user_config_t user_config; +``` + +以上代码建立了一个结构体,该结构体可以存储设置并可用于写入EEPROM。如此这般将无需定义变量,因为在结构体中已然定义。要记住`bool` (布尔)值使用1位, `uint8_t`使用8位, `uint16_t`使用16位。你可以混合搭配使用,但是顺序记错可能会招致麻烦,因为那会改变写入写出的值。 + + `layer_state_set_*`函数中使用了`rgb_layer_change`,使用了`keyboard_post_init_user`和`process_record_user`来配置一切。 + +首先要使用`keyboard_post_init_user,你要加入`eeconfig_read_user()`来填充你刚刚创建的结构体。然后您可以立即使用这个结构来控制您的布局中的功能。就像这样: +```c +void keyboard_post_init_user(void) { + // 调用布局级别的矩阵初始化 + + // 从EEPROM读用户配置 + user_config.raw = eeconfig_read_user(); + + // 如使能,设置默认层 + if (user_config.rgb_layer_change) { + rgblight_enable_noeeprom(); + rgblight_sethsv_noeeprom_cyan(); + rgblight_mode_noeeprom(1); + } +} +``` +以上函数会在读EEPROM配置后立即使用该设置来设置默认层RGB颜色。"raw"的值是从你上面基于"union"创建的结构体中转换来的。 + +```c +uint32_t layer_state_set_user(uint32_t state) { + switch (biton32(state)) { + case _RAISE: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } + break; + case _LOWER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } + break; + case _PLOVER: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } + break; + case _ADJUST: + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } + break; + default: // 针对其他层或默认层 + if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } + break; + } + return state; +} +``` +这样仅在值使能时会改变RGB背光灯。现在配置这个值, 为`process_record_user`创建一个新键码叫做`RGB_LYR`。我们要确保,如果使用正常的RGB代码,使用上面的示例将其关闭,请将其设置为: +```c + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case FOO: + if (record->event.pressed) { + // 按下时做点什么 + } else { + // 释放时做点什么 + } + return false; // 跳过此键的进一步处理 + case KC_ENTER: + // 在按下回车时播放音符 + if (record->event.pressed) { + PLAY_SONG(tone_qwerty); + } + return true; // 让QMK产生回车按下/释放事件 + case RGB_LYR: // 本句让underglow作为层指示,或正常使用。 + if (record->event.pressed) { + user_config.rgb_layer_change ^= 1; // 切换状态 + eeconfig_update_user(user_config.raw); // 向EEPROM写入新状态 + if (user_config.rgb_layer_change) { // 如果层状态被使能 + layer_state_set(layer_state); // 那么立刻更新层颜色 + } + } + return false; + case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // 对于所有的RGB代码 (see quantum_keycodes.h, L400 可以参考) + if (record->event.pressed) { //本句失能层指示,假设你改变了这个…你要把它禁用 + if (user_config.rgb_layer_change) { // 仅当使能时 + user_config.rgb_layer_change = false; // 失能,然后 + eeconfig_update_user(user_config.raw); // 向EEPROM写入设置 + } + } + return true; break; + default: + return true; // 按其他键正常 + } +} +``` +最后你要加入`eeconfig_init_user`函数,所以当EEPROM重置时,可以指定默认值, 甚至自定义操作。想强制重置EEPROM,请用`EEP_RST`键码或[Bootmagic](feature_bootmagic.md)函数。比如,如果要在默认情况下设置RGB层指示,并保存默认值 + +```c +void eeconfig_init_user(void) { // EEPROM正被重置 + user_config.raw = 0; + user_config.rgb_layer_change = true; // 我们想要默认使能 + eeconfig_update_user(user_config.raw); // 向EEPROM写入默认值 + + // use the non noeeprom versions, 还要向EEPROM写入这些值 + rgblight_enable(); // 默认使能RGB + rgblight_sethsv_cyan(); // 默认设置青色 + rgblight_mode(1); // 默认设置长亮 +} +``` + +然后就完事了。RGB层指示会在你想让它工作时工作。这个设置会一直保存,即便你拔下键盘。如果你使用其他RGB代码,层指示将失能,现在它可以做你所想了。 + +### 'EECONFIG' 函数文档 + +* 键盘/修订: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)`和`void eeconfig_update_kb(uint32_t val)` +* 布局: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)`和`void eeconfig_update_user(uint32_t val)` + +`val` 是你想写入EEPROM的值,`eeconfig_read_*`函数会从EEPROM返回一个32位(双字)的值。 + +# 自定义击键-长按临界值(TAPPING_TERM) +默认情况下,击键-长按临界值是全球统一的,并且不能通过键进行配置。对于大多数用户来说这很好。但是在有些情况下,对于`LT`键来说按键延时对双功能键的提升更大,可能是因为有些键比其他的键更容易按住。为了不给每个都自定义键码,本功能可以为每个键定义`TAPPING_TERM`。 + +想使能这个功能的话, 要先在`config.h`加上`#define TAPPING_TERM_PER_KEY`。 + + +## `get_tapping_term`示例实现 + +想要修改基于键码的`TAPPING TERM`,你要向`keymap.c`文件添加如下代码: + +```c +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case SFT_T(KC_SPC): + return TAPPING_TERM + 1250; + case LT(1, KC_GRV): + return 130; + default: + return TAPPING_TERM; + } +} +``` + +### `get_tapping_term` 函数文档 + +不像这篇的其他功能,这个不需要quantum或者键盘级别的函数,只要用户级函数即可。 diff --git a/zh-cn/faq.md b/zh-cn/faq.md new file mode 100644 index 00000000000..3d0b65c6fd2 --- /dev/null +++ b/zh-cn/faq.md @@ -0,0 +1,6 @@ +# 常见问题 + +* [一般问题](faq_general.md) +* [构建和编译QMK](faq_build.md) +* [QMK调试和故障排除](faq_debug.md) +* [布局问题](faq_keymap.md) diff --git a/zh-cn/faq_build.md b/zh-cn/faq_build.md new file mode 100644 index 00000000000..0d9047bc59a --- /dev/null +++ b/zh-cn/faq_build.md @@ -0,0 +1,122 @@ +# 关于构建的常见问题 + +本页所写是QMK构建的常见问题.如果你还没有进行过编译,就看一下[构建环境搭建](getting_started_build_tools.md) 和 [make的说明](getting_started_make_guide.md). + +## 如果您不能在Linux上编程 +您需要适当的权限才能操作设备。对于Linux用户, 请参阅下方有关`udev`规则的说明。如果您对`udev`有问题,解决方法是用`sudo`命令。如果您不熟悉此命令,使用`man sudo`查看其手册或[看这个网页](https://linux.die.net/man/8/sudo). + +在你的主控是ATMega32u4时,以下是使用`sudo`命令的样例: + + $ sudo dfu-programmer atmega32u4 erase --force + $ sudo dfu-programmer atmega32u4 flash your.hex + $ sudo dfu-programmer atmega32u4 reset + +或只用; + + $ sudo make ::dfu + +使用`sudo`运行`make`一般来说**不**推荐,如果可能,尽量使用前一种方法之一。 + +### Linux `udev` 规则 +在Linux上,您需要适当的权限才能访问MCU。你也可以在刷新固件时使用 `sudo`,或把这些文件放到`/etc/udev/rules.d/`。 + +**/etc/udev/rules.d/50-atmel-dfu.rules:** +``` +# Atmel ATMega32U4 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff4", MODE:="0666" +# Atmel USBKEY AT90USB1287 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ffb", MODE:="0666" +# Atmel ATMega32U2 +SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff0", MODE:="0666" +``` + +**/etc/udev/rules.d/52-tmk-keyboard.rules:** +``` +# tmk键盘产品 https://github.com/tmk/tmk_keyboard +SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666" +``` +**/etc/udev/rules.d/54-input-club-keyboard.rules:** + +``` +# Input Club keyboard bootloader +SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", MODE:="0666" +``` + +### 串行设备在Linux上检测不到bootloader模式 +确保您的内核对您的设备有相应的支持。 如果你的设备是 USB ACM, 比如Pro Micro (Atmega32u4),就要加上`CONFIG_USB_ACM=y`. 其他设备可能需要`USB_SERIAL` 及其任何子选项。 + +## DFU Bootloader的未知设备 + +如果您在使用Windows来刷新键盘的时候碰到了问题,检查设备管理器。如果在键盘处于 "bootloader模式"时你看到 "未知设备",说明你可能面临设备问题。 + +重新运行MSYS2上的安装脚本或许会凑效(比如在MSYS2/WSL运行 `./util/qmk_install.sh`) 或者重新安装QMK工具箱也可能会解决你的问题。 + +如果以上方法还是短针攻疽,那您可能需要使用[Zadig Utility](https://zadig.akeo.ie/)。下载此程序, 找到设备问题, 然后选择 `WinUSB`选项, 然后点击"Reinstall driver"。完成后再试试刷新你的键盘。倘若依然徒劳无功,那就尝试所有选项直到好用为止。 + +?> 事实上没有一个驱动的最佳选择,有些选项就是和某些系统相辅相成。但libUSB和WinUSB似乎也算是这里的最佳选择了。 +如果bootloader在设备列表中没有显示,你可能要使能 "List all devices"选项在选项菜单中`Options`,然后找到有问题的bootloader设备。(译者注:在win10中可能为 查看-显示隐藏的设备) + +## USB VID 和 PID +你可以在编辑`config.h`时使用任何你想用的ID值。实际上,使用任何可能未使用的ID都没有问题,除了有极低的与其他产品发生冲突的可能性。 + +大多数QMK主板使用`0xFEED`作为vendor ID。您应该查看其他键盘,以确保选择了唯一的Product ID。 + +也要看看这个。 +https://github.com/tmk/tmk_keyboard/issues/150 + +一也可以在下方链接购买一个唯一的VID:PID。不过个人使用似乎用不着这个。 +- http://www.obdev.at/products/vusb/license.html +- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 + +## AVR的BOOTLOADER_SIZE +注意Teensy2.0++ bootloader的大小是2048字节。有些Makefile注释错了。 + +``` +# Boot Section Size in *bytes* +# Teensy halfKay 512 +# Teensy++ halfKay 2048 +# Atmel DFU loader 4096 (TMK Alt Controller) +# LUFA bootloader 4096 +# USBaspLoader 2048 +OPT_DEFS += -DBOOTLOADER_SIZE=2048 +``` + +## 在MacOS上 `avr-gcc: internal compiler error: Abort trap: 6 (program cc1)` +这是brew更新的问题,导致AVR GCC依赖的符号链接被损坏。 + +解决方案是移除并重新安装所有受影响的模块。 + +``` +brew rm avr-gcc +brew rm dfu-programmer +brew rm dfu-util +brew rm gcc-arm-none-eabi +brew rm avrdude +brew install avr-gcc +brew install dfu-programmer +brew install dfu-util +brew install gcc-arm-none-eabi +brew install avrdude +``` + +### avr-gcc 8.1 和 LUFA + +如果你把avr-gcc升级到7以上你可能会遇到关于LUFA的问题。比如: + +`lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h:380:5: error: 'const' attribute on function returning 'void'` + +那你就需要在brew中把avr-gcc回退到7。 + +``` +brew uninstall --force avr-gcc +brew install avr-gcc@8 +brew link --force avr-gcc@8 +``` + +### 我刷新了我的键盘但是键盘不工作/按键没有注册 - 而且还是ARM的 (rev6 planck, clueboard 60, hs60v2, etc...) (Feb 2019) +由于EEPROM在基于ARM的芯片上的工作原理,保存的设置可能不再有效。这会影响默认层,而且*或许*在某些情况下,会使键盘不好用,我们仍在调查这些情况。重置EEPROM将解决此问题。 + +[Planck rev6键盘重置EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) 是用于强制重置EEPROM的。刷入这个文件后,再次刷入正常固件,这会将键盘恢复到_正常_工作状态。 +[Preonic rev3键盘重置EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) + +如果以任何形式启用了bootmagic, 那么您还需要(看[Bootmagic文档](feature_bootmagic.md) 以及键盘信息,以了解如何执行此操作的详细信息). diff --git a/zh-cn/faq_debug.md b/zh-cn/faq_debug.md new file mode 100644 index 00000000000..71b575ea00b --- /dev/null +++ b/zh-cn/faq_debug.md @@ -0,0 +1,141 @@ +# 调试的常见问题 + +本篇详细介绍了人们在键盘故障排除时的各种常见问题。 + +# 调试控制台 + +## `hid_listen` 无法识别设备 +当设备的调试控制台未就绪时,您将看到如下内容: + +``` +Waiting for device:......... +``` + +插入设备后,*hid_listen*找到该设备,您将收到以下消息: + +``` +Waiting for new device:......................... +Listening: +``` + +如果您无法获得这条“Listening:”消息,请尝试在[Makefile]中使用 `CONSOLE_ENABLE=yes` + +在Linux这样的操作系统上,你可能需要一些权限。 +- 使用`sudo hid_listen` + +## 控制台没有返回消息 +检查: +- *hid_listen* 找到了你的设备。看前面。 +- 输入**Magic**+d打开调试。详见[Magic Commands](https://github.com/tmk/tmk_keyboard#magic-commands)。 +- 设置`debug_enable=true` ,一般存在于**matrix.c**的`matrix_init()`中。 +- 尝试使用'print'函数而不要用调试输出。详见**common/print.h**。 +- 断开其他有控制台功能的设备。 详见[Issue #97](https://github.com/tmk/tmk_keyboard/issues/97)。 + +## Linux或UNIX这样的系统如何请求超级用户权限 +用'sudo'来执行*hid_listen*就有权限了。 +``` +$ sudo hid_listen +``` + +或者把一个文件放到规则文件夹来为TMK设备添加*udev规则*,不同系统的目录可能有所不同。 + +文件: /etc/udev/rules.d/52-tmk-keyboard.rules(在Ubuntu系统的情况下) +``` +# tmk keyboard products https://github.com/tmk/tmk_keyboard +SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666" +``` + +*** + +# 其他 +## 安全注意事项 + +你应该不想要把你的键盘变成"砖头"吧,就是变成没法重写固件的那种。 +下面讲解一些参数来告诉你什么风险很大(其实也不是很大)。 + +- 假如你键盘表面没有设计重置键"RESET", 那你要进入bootloader的话就要按PCB上的RESET了。 + 按PCB上的RESET要拧开键盘底部。 +- 如果 tmk_core / common 里面的文件丢失键盘可能失灵。 +- .hex太大可能不太好; `make dfu` 会删除块,检验大小(咦?好像反了...)。 + 一但出错,刷新键盘失败的话就困在DFU出不去了。 + - 所以, 要知道大小限制。 Planck键盘上.hex文件最大大小是 is 7000h (十进制是28672) + +``` +Linking: .build/planck_rev4_cbbrowne.elf [OK] +Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] + +Size after: + text data bss dec hex filename + 0 22396 0 22396 577c planck_rev4_cbbrowne.hex +``` + + - 上面那个文件大小是 22396/577ch,比28672/7000h小 + - 当你有一个合适的.hex文件时,你就要重试加载那个了 + - 您在键盘Makefile中的某些选项可能消耗额外内存;注意以下这几个 + BOOTMAGIC_ENABLE, MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE, API_SYSEX_ENABLE +- DFU 工具/不/可以写入bootloader (unless you throw in extra fruit salad of options), + 所以还是有点危险的 +- EEPROM大概有100000次循环寿命。不要总是频繁重写固件;EEPROM会玩坏的。 +## 全键无冲不好用 +首先你要在**Makefile**用如下命令编译固件`NKRO_ENABLE`。 + +全键无冲还不好用的话试着用`Magic` **N** 命令(默认是`LShift+RShift+N`)。这个命令会在**全键无冲**和**六键无冲**之间临时切换。有些情况**全键无冲**不好用你就需要使用**六键无冲**模式,尤其是在BIOS中。 + +如果你的固件使用`BOOTMAGIC_ENABLE`编译的你要用`BootMagic` **N** 命令(默认`Space+N`)打开开关。这个设置保存在EEPROM中并保存在电源循环中。 + + +https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch + + +## 指点杆需要复位电路(PS/2 鼠标支持) +如果没有复位电路,由于硬件初始化不正确,您将得到不一致的结果。查看TPM754复位电路。 + +- http://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 +- http://www.mikrocontroller.net/attachment/52583/tpm754.pdf + + +## 矩阵不可读16以上的列 +当列超过16时[matrix.h]的`read_cols()`中,用`1UL<<16`而不要用`1<<16`。 + +在C语言中`1` 是一个[int] 类型的[16 bit]值,在AVR中你不能左移大于15次。如果你使用`1<<16`的话会得到意外的零。你要用 [unsigned long]类型,比如`1UL`。 + +http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 + +## 特殊额外键不起作用(系统,音频控制键) +你要在`rules.mk`定义`EXTRAKEY_ENABLE`在QMK中使用它们。 + +``` +EXTRAKEY_ENABLE = yes # 音频控制和系统控制 +``` + +## 睡眠唤醒不好用 + +在Windows查看设备管理器中该键盘设备属性中电源管理选项卡中的`允许此设备唤醒计算机(O)`是否勾选。同时看一眼BIOS设置。 + +在主机睡眠时按下任何键都可以唤醒了。 + +## 使用Arduino? + +**注意Arduino的针脚名字和主控芯片的不一样。** 比如, Arduino的`D0`并不是`PD0`。自己用原理图捋一下电路。 + +- http://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf +- http://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf + +Arduino Leonardo和micro使用**ATMega32U4**,该芯片TMK可用,但Arduino的bootloader会导致问题。 + +## USB 3 兼容性 +据传说有些人用USB3接口会有问题,用USB2的试试。 + + +## Mac 兼容性 +### OS X 10.11 和集线器 +https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 + + +## 对于BIOS (UEFI)/恢复(睡眠和唤醒)/重新启动 有问题 +有人说他们的键盘在BIOS中,或许是恢复(睡眠和唤醒)后不工作. + +截止至目前,其根本原因未知,不排除与某些构建选项有关。试着在Makefile中失能`CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE`这样的选项,也试试其他的。 + +https://github.com/tmk/tmk_keyboard/issues/266 +https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/zh-cn/faq_general.md b/zh-cn/faq_general.md new file mode 100644 index 00000000000..4949acb8c9d --- /dev/null +++ b/zh-cn/faq_general.md @@ -0,0 +1,19 @@ +# + +## QMKʲô? + +[QMK](https://github.com/qmk), ӻе(Quantum Mechanical Keyboard)дһȺԴΪƼ̿ĹߡǴ[QMK̼](https://github.com/qmk/qmk_firmware)ʼ[TMK](https://github.com/tmk/tmk_keyboard)ħķֲ档 + +### Ϊʲô(Quantum)? + + + +## QMKTMKʲô? + +TMK[Jun Wako](https://github.com/tmk)ƺִСQMKʼ[Jack Humbert](https://github.com/jackhumbert)ΪPlanck̴TMKֲ档һʱJackķֲͺTMKȥԶˣ2015꣬JackQMK + +Ӽ۵QMKTMKһЩ¹ܶɵġQMKչ˿õļ룬ʹ߼ܽһḻ `S()`, `LCTL()`, `MO()`ȫ[](keycodes.md). + +ӹ̵TMKԼάйٷֵ֧ļֻ̣кСһ֧֡άѴڷֲΪ̴ķֲ档Ĭֺ֧ٵļ룬ûͨ˷֡QMKͨйֺֿͼ̣ǻз׼PRͼı֤άͬʱQMKСҲڱҪʱ + +ַŵȱ㣬ҴʱTMKQMK֮ diff --git a/zh-cn/faq_keymap.md b/zh-cn/faq_keymap.md new file mode 100644 index 00000000000..7fb434b4c89 --- /dev/null +++ b/zh-cn/faq_keymap.md @@ -0,0 +1,151 @@ +# 布局常见问题 + +本页本页包含人们经常遇到的关于布局的问题。如果你觉得没什么问题,请先看[布局概览](keymap.md)。 + +## 我能用什么键码? +看[键码](keycodes.md)你可以找到你能用的键码索引。可以的话这些链接可以连接到更广泛的文档。 + +键码实际上定义在[common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/keycode.h). + +## 默认的键码什么样? + +世界上有三种标准键盘设计,分别是:ANSI, ISO, and JIS. 主要是北美用ANSI(译者注:中国很多键盘使用这个), 欧洲和非洲主要使用ISO,日本使用JIS。未提及的区域通常使用ANSI或ISO。与这些设计对应的键代码如下所示: + + +![键盘设计图](https://i.imgur.com/5wsh5wM.png) + +## 我有一些键变成了其他功能或者不工作了 + +QMK有两个功能,Bootmagic和命令行,它允许您在运行中更改键盘的行为。该功能包括但不仅限于, 交换Ctrl/Caps,关闭界面,交换Alt/Gui,交换 Backspace/Backslash,禁用所有键,以及其他的行为改变。 + +快速解决方法是插入键盘时按住`Space`+`Backspace`。该操作将重置已保存设置,让这些键回复初始功能。这招不好用的话参阅下方: + +* [Bootmagic](feature_bootmagic.md) +* [命令](feature_command.md) + +## 菜单键不好用 + +现在大多数键盘 `KC_RGUI`和`KC_RCTL`中间的键子叫做`KC_APP`。这是因为在这个键子发明之前相关标准里就已经有键叫做`MENU(菜单)`了,所以微软叫他`APP(应用)`键。 + +## `KC_SYSREQ` 不工作 +使用抓屏的键码(`KC_PSCREEN`或`KC_PSCR`)而不用`KC_SYSREQ`。组合键'Alt + Print Screen'会被当作'System request'。 + +见[issue #168](https://github.com/tmk/tmk_keyboard/issues/168)和 +* http://en.wikipedia.org/wiki/Magic_SysRq_key +* http://en.wikipedia.org/wiki/System_request + +## 电源键不工作 + +这有点让人困惑,QMK有两个"Power(电源)"键码: `KC_POWER` 在键盘/小键盘的HID使用页面中,`KC_SYSTEM_POWER` (或者叫`KC_PWR`)在用户页。 + +前者只能被macOS识别,但是后者,即`KC_SLEP`和`KC_WAKE`三大主要操作系统全都支持,所以推荐使用这两个。Windows下这些键立即生效,macOS要长按直到弹出对话框。 + +## 自动大小写锁定 +可以解决'the'问题(正常应为The)。我经常在输入'The'时不慎输入了'the'或者'THe'。自动大小写锁定可以修正此类问题。详见下方链接。 +https://github.com/tmk/tmk_keyboard/issues/67 + +## 修改 键/层 卡住 +除非正确配置层切换,否则修改键或层可能会卡住。 +对于修改键和图层操作,必须把`KC_TRANS`放到目标层的相同位置,用于注销修改键或在释放事件时返回到上一层。 +* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching +* http://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 +* https://github.com/tmk/tmk_keyboard/issues/248 + + +## 机械自锁开关支持Mechanical Lock Switch Support + +本功能用于*机械自锁开关*比如[this Alps one](http://deskthority.net/wiki/Alps_SKCL_Lock)。你可以通过向`config.h`添加以下宏来使能该功能: + +``` +#define LOCKING_SUPPORT_ENABLE +#define LOCKING_RESYNC_ENABLE +``` + +在使能该功能后,要在键盘中使用`KC_LCAP`, `KC_LNUM` 和 `KC_LSCR`这三个键码。 + +远古机械键盘偶尔会有自锁机械开关,现在几乎没有了。***大多数情况下你不需要使用该功能,且要使用`KC_CAPS`, `KC_NLCK`和`KC_SLCK`这三个键码。*** + +## 输入ASCII之外的特殊字符比如Cédille 'Ç' + +请见[Unicode](feature_unicode.md)功能。 + +## macOS上的`Fn` + +不像大多数FN键,苹果上那个有自己的键码...呃,基本上算吧。 他取缔了基本6键无冲HID报告的第六个键码 -- 所以苹果键盘其实是5键无冲的。 + +技术上说QMK可以发送这个键。但是,这样做需要修改报告格式以添加FN键的状态。这还不是最糟糕的,你的键盘的VID和PID和真的苹果键盘不一样的话还不会被识别。 +QMK官方支持这个会被律师函的,所以就当我没说过。 + +详见[issue#2179](https://github.com/qmk/qmk_firmware/issues/2179)。 + + +## Mac OSX的媒体控制键 +#### KC_MNXT 和 KC_MPRV 在Mac上不好用 +使用 `KC_MFFD`(`KC_MEDIA_FAST_FORWARD`) 和 `KC_MRWD`(`KC_MEDIA_REWIND`),不要用 `KC_MNXT` 和 `KC_MPRV`. +详见 https://github.com/tmk/tmk_keyboard/issues/195 + + +## Mac OSX中支持那些键? +你可以从此源码中获知在OSX中支持哪些键码 + +`usb_2_adb_keymap` 阵列映射 键盘/小键盘 页用于ADB扫描码(OSX内部键码). + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c + +`IOHIDConsumer::dispatchConsumerEvent`会处理用户页面用法。 + +https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp + + +## Mac OSX中的JIS键 +岛国特别键比如`無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)`OSX是不是别的。You can use **Seil** to enable those keys, try following options. + +* 在电脑键盘上使能NFER键 +* 在电脑键盘上使能XFER键 +* 在电脑键盘上使能KATAKAN键 + +https://pqrs.org/osx/karabiner/seil.html + + +## RN-42蓝牙模块与Karabiner不能有效协同工作 +Karabiner - Mac OSX的改键软件 - 默认RN-42模块是不会被响应的。想要Karabiner和你的键盘协同工作你要使能此选项: +https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 + +此问题详见下方链接。 +https://github.com/tmk/tmk_keyboard/issues/213 +https://github.com/tekezo/Karabiner/issues/403 + + +## Esc 和 ` 双功能键 + +请见[Grave Escape](feature_grave_esc.md)功能。 + +## Mac OSX的弹出键 +`KC_EJCT` 键码在OSX可以使用 https://github.com/tmk/tmk_keyboard/issues/250 +似乎Windows10会忽略该键码,Linux/Xorg可以识别该键码但默认不映射。 + +目前尚不清楚如何在真正的苹果键盘按出弹出键。HHKB使用`F20`用于弹出键(`Fn+f`),该功能在MAC模式有效但不保证与苹果弹出键码相符。 + + +## `action_util.c`中的 `weak_mods`和`real_mods`是什么 +___待改善___ + +real_mods 用于保存实际(物理)修改键的实际状态。 +weak_mods 用于保存虚拟或临时修改键,它将不会影响实际修改键。 + +以按下左侧Shift键然后输入ACTION_MODS_KEY(LSHIFT, KC_A)为例, + +在weak_mods时, +* (1) 按下不抬起左Shift: real_mods |= MOD_BIT(LSHIFT) +* (2) 按 ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods |= MOD_BIT(LSHIFT) +* (3) 抬起 ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods &= ~MOD_BIT(LSHIFT) +real_mods 还是保持在修改状态。 + +在没有weak_mods时, +* (1) 按下不抬起左Shift: real_mods |= MOD_BIT(LSHIFT) +* (2) 按 ACTION_MODS_KEY(LSHIFT, KC_A): real_mods |= MOD_BIT(LSHIFT) +* (3) 抬起 ACTION_MODS_KEY(LSHIFT, KC_A): real_mods &= ~MOD_BIT(LSHIFT) +此时real_mods失去‘实际左Shift’的状态。 + +weak_mods和real_mods现已全部加入键盘数据包发送豪华套餐。 +https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/zh-cn/getting_started_getting_help.md b/zh-cn/getting_started_getting_help.md new file mode 100644 index 00000000000..8c0ebaa2438 --- /dev/null +++ b/zh-cn/getting_started_getting_help.md @@ -0,0 +1,15 @@ +# 获得帮助 + +有很多方法来获得关于QMK的帮助. + +## 实时聊天 + +你可以在我们的主要[Discord服务器](https://discord.gg/Uq7gcHh)找到QMK的开发者和用户。有很多讨论固件的不同频道, 工具箱(Toolbox), 硬件,配置工具(configurator). + +## OLKB Subreddit + +QMK的官方论坛是[/r/olkb](https://reddit.com/r/olkb) 在[reddit.com](https://reddit.com)上. + +## GitHub的Issue + +你可以在GitHub上 [提出issue](https://github.com/qmk/qmk_firmware/issues).当您的问题需要长期讨论或调试时,这尤其方便。 diff --git a/zh-cn/getting_started_github.md b/zh-cn/getting_started_github.md new file mode 100644 index 00000000000..9a01e43b7fd --- /dev/null +++ b/zh-cn/getting_started_github.md @@ -0,0 +1,65 @@ +# 如何在QMK中使用GitHub + +GitHub can be a little tricky to those that aren't familiar with it - this guide will walk through each step of forking, cloning, and submitting a pull request with QMK. + +?> 本教程假设您已安装GitHub,并且您喜欢使用命令行工作。 + +首先 [GitHub上的QMK页面](https://github.com/qmk/qmk_firmware), 您能看到右上方有个按钮写着"Fork": + +![从GitHub上分叉](http://i.imgur.com/8Toomz4.jpg) + +如果你是某组织成员,你将需要选择分叉到哪个账户。一般情况下, 你是想要分叉到你的私人账户下。当你完成分叉 (有时需要等一会), 点击"Clone or Download" 按钮: + +!从GitHub下载](http://i.imgur.com/N1NYcSz.jpg) + +你要选择 "HTTPS", 然后选择链接复制: + +![HTTPS链接](http://i.imgur.com/eGO0ohO.jpg) + +然后,在命令行输入`git clone --recurse-submodules `,然后粘贴你的链接: + +``` +user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git +Cloning into 'qmk_firmware'... +remote: Enumerating objects: 9, done. +remote: Counting objects: 100% (9/9), done. +remote: Compressing objects: 100% (5/5), done. +remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 +Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. +Resolving deltas: 100% (119972/119972), done. +... +Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' +Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' +Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' +Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' +Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2' +``` + +现在你本地计算机有QMK的分叉了,你可以添加你的布局了, 为你的键盘编译并刷新固件吧。如果你觉得你的修改很不错, 你可以添加,提交,然后想你的分叉推出(pull)你的改变,像这样: + +``` +user@computer:~$ git add . +user@computer:~$ git commit -m "adding my keymap" +[master cccb1608] adding my keymap + 1 file changed, 1 insertion(+) + create mode 100644 keyboards/planck/keymaps/mine/keymap.c +user@computer:~$ git push +Counting objects: 1, done. +Delta compression using up to 4 threads. +Compressing objects: 100% (1/1), done. +Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. +Total 1 (delta 1), reused 0 (delta 0) +remote: Resolving deltas: 100% (1/1), completed with 1 local objects. +To https://github.com/whoeveryouare/qmk_firmware.git + + 20043e64...7da94ac5 master -> master +``` + +现在你的改动已经在你GitHub上的分支中了 - 如果你回到这 (`https://github.com/你的GitHub账户名/qmk_firmware`) ,你可以点击下方所示按钮创建 "New Pull Request": + +![新的 Pull Request](http://i.imgur.com/DxMHpJ8.jpg) + +现在你可以看到你所做的一切 - 如果看起来不错, 就可以点击 "Create Pull Request"定稿了: + +![创建Pull Request](http://i.imgur.com/Ojydlaj.jpg) + +提交后,我们会开跟你说你的改动,要求您进行更改, 并最终接受您的更改!感谢您为QMK做的贡献 :) diff --git a/zh-cn/getting_started_introduction.md b/zh-cn/getting_started_introduction.md new file mode 100644 index 00000000000..b977b633909 --- /dev/null +++ b/zh-cn/getting_started_introduction.md @@ -0,0 +1,54 @@ +# 介绍 + +本页解释了使用QMK项目所需的基本信息。它假定您能熟练使用Unix shell,但您不熟悉C语言也不熟悉使用make编译。 + +## 基本QMK结构 + +QMK是[Jun Wako](https://github.com/tmk)的[tmk_keyboard](https://github.com/tmk/tmk_keyboard)工程的一个分叉。经过更改的TMK原始代码放在`tmk_core` 文件夹中。 QMK增加的新东西可以在 `quantum` 文件夹中找到。 键盘项目可以在 `handwired`(手动飞线) 和 `keyboard`(PCB键盘)这两个文件夹找到。 + +### 用户空间结构 + +在`users`文件夹里面的目录是每个用户的目录。这个文件夹里面放的是用户们在不同键盘都能用到的代码。详见[用户空间特性](feature_userspace.md) + +### 键盘项目结构 + +在`keyboards`文件夹和他的子文件夹`handwired`中就是各个键盘的项目了,比如`qmk_firmware/keyboards/clueboard`。内部结构与如下: + +* `keymaps/`: 可以构建的不同布局 +* `rules.mk`: 用来设置 "make" 命令默认选项的文件。别直接编辑这个文件,你应该使用具体某个布局的 `rules.mk`. +* `config.h`: 用于设置默认编译选项的文件。别直接编辑这个文件, 你应该使用具体某个布局的 `config.h`. + +### 布局结构 + +在各个布局的文件夹,你能找到以下文件。只有 `keymap.c` 是必要的, 如果其他文件找不到就会直接选择默认选项。 + +* `config.h`: 配置布局的选项 +* `keymap.c`: 布局的全部代码, 必要文件 +* `rules.mk`: 使能的QMK特性 +* `readme.md`:介绍你的布局,告诉别人怎么使用,附上功能说明。请将图片上传到imgur等图床(译者注:imgur可能已被墙,为了方便国人访问,建议使用国内可以直接访问的图床)。 + +# `config.h` 文件 + +有三个重要的`config.h` 位置: + +* 键盘 (`/keyboards//config.h`) +* 用户空间 (`/users//config.h`) +* 布局 (`/keyboards//keymaps//config.h`) + +构建系统按照上述顺序自动获取配置文件。如果要覆盖由上一个 `config.h` 所做的设置,您需要首先为要更改的设置包含一些样板代码。 + +``` +#pragma once +``` + +要覆盖上一个 `config.h` 所做的设置,你要先 `#undef` 然后再 `#define` 这个设置. + +样板代码和设置看起来像这样: + +``` +#pragma once + +// 像下面那样覆盖设置(MY_SETTING指的是你要覆盖的设置项)! +#undef MY_SETTING +#define MY_SETTING 4 +``` diff --git a/zh-cn/newbs.md b/zh-cn/newbs.md new file mode 100644 index 00000000000..8c36b0d24b0 --- /dev/null +++ b/zh-cn/newbs.md @@ -0,0 +1,23 @@ +# QMK菜鸟教程 + +QMK是为你机械硬盘设计的的一个强大的开源固件。使用QMK可以很简单的让你的定制键盘变得强大。看完这篇文章,无论你是菜鸟还是大佬,都可以顺利的使用QMK来定制键盘。 + +你是否为不知道你的键盘能不能运行QMK而苦恼? 如果你的机械键盘是你自己做的,那么这把键盘一般可以运行QMK。我们提供了[一大堆自制键盘](http://qmk.fm/keyboards/), 所以即便你的键盘不能运行QMK你也很容易能找到满足你需求的键盘。 + +## 概览 + +这个教程有7个主要部分: + +* [新手上路](newbs_getting_started.md) +* [用命令行构建你的第一个固件](newbs_building_firmware.md) +* [用在线界面构建你的第一个固件](newbs_building_firmware_configurator.md) +* [刷新固件](newbs_flashing.md) +* [测试和调试](newbs_testing_debugging.md) +* [Git最佳实践](newbs_best_practices.md) +* [其他学习资源](newbs_learn_more_resources.md) + +这份教程旨在帮助没有固件构建经验的人,也是根据该目的做出选择和建议。这些程序有很多替代方法,大部分替代我们都支持。如果你对完成一个任务有疑问,可以[向我们寻求帮助](getting_started_getting_help.md). + +## 其他资源 + +* [Thomas Baart的 QMK基础博客](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 这是一个用户创建的博客,涵盖了为新手准备的使用QMK的基础知识。 diff --git a/zh-cn/newbs_best_practices.md b/zh-cn/newbs_best_practices.md new file mode 100644 index 00000000000..fa58dc75e87 --- /dev/null +++ b/zh-cn/newbs_best_practices.md @@ -0,0 +1,163 @@ +# 最佳实践 + +## 或者说, "我应如何学会不再担心并开始爱上Git。" + +本文档旨在指导新手以最佳方式获得为QMK做出贡献的丝滑体验。我们将介绍为QMK做出贡献的过程,详细介绍使这项任务更容易的一些方法,然后我们将制造一些问题,来教你如何解决它们。 + +本文假设了一些内容: + +1. 一有个GitHub账户, 并[创建qmk_firmware仓库分叉](getting_started_github.md)到你的帐户. +2. 你已经[建立你的构建环境](newbs_getting_started.md?id=environment-setup). + + +## 你分叉的主分支: 一直在上传,但不要提交 + +十分推荐您在QMK开发过程中无论开发是否完成都要保持你的 `master` 分支更新,但是 ***一定不要*** 提交。相反,你应该在一个开发分叉中做出你所有修改并在开发时提交pull request。 + +减少合并冲突的可能性 — 两个或多个用户同时编辑文件的同一部分的实例 — 保持 `master` 分支最新,并创建一个新的分支来开始新的开发。 + +### 更新你的主分支 + +保持你的 `master` 更新, 推荐你添加QMK Firmware仓库作为Git的远程仓库,想这么做的话, 你可以打开你的Git命令行接口然后输入: + +``` +git remote add upstream https://github.com/qmk/qmk_firmware.git +``` + +运行 `git remote -v`, 来确定这个仓库已经添加,以下是回显: + +``` +$ git remote -v +origin https://github.com//qmk_firmware.git (fetch) +origin https://github.com//qmk_firmware.git (push) +upstream https://github.com/qmk/qmk_firmware.git (fetch) +upstream https://github.com/qmk/qmk_firmware.git (push) +``` + +现在添加已完成,你可以用`git fetch upstream`来检查仓库的更新. 这会检索branches 和 tags — 统称为"refs" — 从QMK仓库, 也就是 `upstream`。我们可以比较我们的分叉和QMK的 `origin` 数据的不同。 + +要更新你的分叉的主分支,请运行以下命令,在每行之后按Enter键: + +``` +git checkout master +git fetch upstream +git pull upstream master +git push origin master +``` + +这回切换到你的`master` 分支, 检索你QMK仓库的refs, 下载当前QMK `master` 分支到你的电脑, 并上传到你的分叉. + +### 做改动 + +你可以输入以下命令来创建一个新的分支来做改动: + +``` +git checkout -b dev_branch +git push --set-upstream origin dev_branch +``` + +这回建立一个叫做 `dev_branch`的新分支, 检查一下, 然后想你的分叉保存分支. 使用 `--set-upstream` 参数来告诉git使用你的分叉并且当每次你对你的分支用`git push` 或 `git pull`时要使用`dev_branch`。 它仅需要在第一次push的时候使用;然后你就可以很安全的用 `git push` 或 `git pull`, 并不需要其他参数了。 + +!> 使用 `git push`, 你可以用 `-u` 来代替 `--set-upstream` — `-u`是`--set-upstream`的简写。 + +您可以将您的分支命名为您想要的任何名称,但建议将其命名为与您要进行的更改相关的内容。 + +默认情况下 `git checkout -b` 在已经检出的分支上建立新的分支。您可以将新的分支建立在未检出的现有分支的基础上,方法是将现有分支的名称添加到命令: + +``` +git checkout -b dev_branch master +``` + +现在您已经有了一个开发分支,那么就打开您的文本编辑器并进行您需要做的任何更改。建议对您的分支进行许多小的提交;这样,任何引起问题的更改都可以在需要时更容易地跟踪和撤消。要进行更改,编辑并保存任何需要更新的文件,请将它们添加到Git的 *staging area* ,然后将它们提交到您的分支: + +``` +git add path/to/updated_file +git commit -m "My commit message." +``` + +` git add`添加已更改到Git的*临时区域*也就是Git的“加载区域”的文件。其中包含使用 `git commit` 命令 *提交* 的并已经保存到仓库的更改。建议您使用描述性的提交消息,这样您就可以一目了然地知道更改了什么。 + +!> 如果你修改了很多文件,但所有的文件都是同一个更改的一部分,你可以用 `git add .` 来添加当前目录中所有已更改的文件而不是单独添加每个文件. + +### 发布更改 + +最后一步是将更改推送到您的分叉。 输入 `git push`来推送. 现在Git将`dev_branch`的当前状态发布到您的分叉。 + + +## 解决合并冲突 + +有时,当您在某个分支中的工作需要很长时间才能完成时,其他人所做的更改与您在打开pull request时对该分支所做的更改相冲突。这称为*rebase* 即合并冲突,当多个人编辑同一文件的同一部分时会发生这种情况。 + +### 重新调整您的更改 + +*rebase*是Git的一种方法,它获取在某一点上应用的更改,撤销它们,然后将相同的更改应用到另一点。在合并冲突的情况下,您可以重新设置您的分支以获取在创建分支时和当前时间之间的那段时间所做的更改。 + +运行以下命令来开始: + +``` +git fetch upstream +git rev-list --left-right --count HEAD...upstream/master +``` + + 这里的`git rev-list` 命令返回当前分支和qmk的主分支之间不同的提交数。我们首先运行`git fetch`,以确保我们有代表upstream仓库的refs。 `git rev-list` 命令的回显有两个数字: + +``` +$ git rev-list --left-right --count HEAD...upstream/master +7 35 +``` + +第一个数字表示自创建以来当前分支的提交数, 第二个数字是自创建当前分支以来对 `upstream/master` 进行的提交数, 因此, 当前分支中未记录变动。 + +既然知道当前分支和upstream仓库的当前状态,我们可以开始一个rebase操作: + +``` +git rebase upstream/master +``` + +这就是让Git撤销当前分支上的提交,然后根据QMK的主分支重新应用它们。 + +``` +$ git rebase upstream/master +First, rewinding head to replay your work on top of it... +Applying: Commit #1 +Using index info to reconstruct a base tree... +M conflicting_file_1.txt +Falling back to patching base and 3-way merge... +Auto-merging conflicting_file_1.txt +CONFLICT (content): Merge conflict in conflicting_file_1.txt +error: Failed to merge in the changes. +hint: Use 'git am --show-current-patch' to see the failed patch +Patch failed at 0001 Commit #1 + +Resolve all conflicts manually, mark them as resolved with +"git add/rm ", then run "git rebase --continue". +You can instead skip this commit: run "git rebase --skip". +To abort and get back to the state before "git rebase", run "git rebase --abort". +``` + +这告诉我们有一个合并冲突,并给出带有冲突的文件的名称。在文本编辑器中打开冲突的文件,在该文件的某个位置,您会发现如下内容: + +``` +<<<<<<< HEAD +

For help with any issues, email us at support@webhost.us.

+======= +

Need help? Email support@webhost.us.

+>>>>>>> Commit #1 +``` + + `<<<<<<< HEAD`行标记合并冲突的开始, `>>>>>>> Commit #1` 行标记结束, 冲突选项被 `=======`分隔。`HEAD`那端的部分来自文件的qmk master版本,标记有commit消息的部分来自当前的分支持和提交。 + +因为Git跟踪 *对文件的更改* 而不是直接跟踪文件的内容,所以如果Git在提交之前找不到文件中的文本,它将不知道如何编辑该文件。重新编辑文件将解决冲突。进行更改,然后保存文件。 + +``` +

Need help? Email support@webhost.us.

+``` + +现在运行: + +``` +git add conflicting_file_1.txt +git rebase --continue +``` + +Git记录对冲突文件的更改,并继续应用来自我们的分支的提交,直到它到达末尾。 diff --git a/zh-cn/newbs_building_firmware.md b/zh-cn/newbs_building_firmware.md new file mode 100644 index 00000000000..fc43583c2b0 --- /dev/null +++ b/zh-cn/newbs_building_firmware.md @@ -0,0 +1,81 @@ +# 构建第一个固件 + +现在您已经建立了构建环境,就可以开始构建自定义固件了。对于本指南的这一部分,我们将在3个程序之间切换——文件管理器、文本编辑器和终端窗口。请保持所有3个程序打开,直到您完成并对键盘固件满意。 + +如果您在按照指南第一部分的操作之后关闭并重新打开了终端窗口,请不要忘记输入“cd qmk_firmware”,来使您的终端位于正确的目录。 + +## 导航到您的keymaps文件夹 + +首先导航到键盘的 `keymaps` 文件夹. + +?> 如果您使用的是MacOS或Windows,可以使用以下命令轻松地打开keymaps文件夹。 + +?> macOS: + + open keyboards//keymaps + +?> Windows: + + start .\\keyboards\\\\keymaps + +## 创建`default` 布局副本 + +打开`keymaps`文件夹后,您将需要创建`default`文件夹的副本。我们强烈建议您将文件夹命名为与GitHub用户名相同的名称,但您也可以使用任何您想使用的名称,只要它只包含小写字母、数字和下划线字符。 + +要自动执行此过程,您还可以选择运行`new_keymap.sh`脚本。 + +导航到`qmk_firmware/util` 目录然后输入以下命令: + +``` +./new_keymap.sh +``` + +例如,一个名字叫ymzcdg的用户要创建1up60hse的布局,他需要输入 + +``` +./new_keymap.sh 1upkeyboards/1up60hse ymzcdg +``` + +## 在你最钟爱的文本编辑器中打开`keymap.c` + +打开你的`keymap.c`. 在这个文件中,您可以找到控制键盘行为的结构。 在你的`keymap.c` 的顶部有一些让布局更易读的define和enum。在靠下的位置你会找到一行和下面这句很像的: + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +从这一行开始便是层列表。这行下面你会看到包括 `LAYOUT` 或 `KEYMAP`这两个词的几行, 从这些行开始就是层。在这一行下面是组成该特定层的键的列表。 + +!> 编辑您的keymap文件时,注意不要添加或删除任何逗号。如果这样做,您将阻止您的固件编译,并且您可能不容易找出多余的或缺少的逗号在哪里。 + +## 根据您的喜好自定义布局 + +如何完成这一步骤完全取决于您。改变一直困扰着你的问题,或者完全重做所有的事情。如果您不需要全部图层,可以删除图层,或者将图层总数增加到32个。查看以下文档,了解可以在此处定义的内容: + +* [键码](keycodes.md) +* [特性](features.md) +* [问题与解答](faq.md) + +?> 当你明白布局是怎么工作时,您也要让每次改变尽可能小。一次改变很大在调试时找出问题会十分困难。 + +## 构建你的固件 + +完成对布局的更改后,您就要构建固件了。为此,请返回终端窗口并运行build命令: + + make : + +例如,如果您的keymap名为“xyverz”,并且您正在为rev5 planck构建一个keymap,那么您将使用此命令: + + make planck/rev5:xyverz + +在编译过程中,你将看到屏幕上有很多输出,通知您正在编译哪些文件他应该以与下文类似的输出结束: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex [OK] + * File size is fine - 18392/28672 +``` + +## 刷新你的固件 + +请移步 [Flashing Firmware](newbs_flashing.md) 来继续。 diff --git a/zh-cn/newbs_flashing.md b/zh-cn/newbs_flashing.md new file mode 100644 index 00000000000..05a9eb55eef --- /dev/null +++ b/zh-cn/newbs_flashing.md @@ -0,0 +1,307 @@ +# 刷新你的键盘 + +现在您已经构建了一个自定义固件文件,那么您就需要刷新键盘了。 + +## 用QMK工具箱刷新键盘 + +刷新键盘的最简单方法是使用[QMK 工具箱](https://github.com/qmk/qmk_toolbox/releases). + +但是,QMK工具箱目前仅适用于Windows和MacOS。如果您使用的是Linux(或者只是希望从命令行刷新固件),则必须使用 [方法概述](newbs_flashing.md#flash-your-keyboard-from-the-command-line). + +### 将文件加载到QMK工具箱中 + +首先打开QMK工具箱应用程序。您将要在访达或资源管理器中找到固件文件。您的键盘固件可能是两种格式之一`.hex`或`.bin`。qmk会尝试将键盘的相应文件复制到“qmk_firmware”根目录中。 + +?> 如果您在Windows或MacOS上,可以使用以下命令轻松地在资源管理器或访达中打开当前固件文件夹。 + +?> Windows: + + start . + +?> macOS: + + open . + +固件文件始终遵循此命名格式: + + _.{bin,hex} + +例如,使用 `default` 布局的 `plank/rev5` 将使用以下名字: + + planck_rev5_default.hex + +找到固件文件后,将其拖到QMK工具箱中的“Local file”框中,或单击“Open”并导航到固件文件的存储位置。 + +### 将键盘置于DFU(Bootloader)模式 + +要刷新自定义固件,您必须将键盘置于特殊的刷新模式。在此模式下,您将无法键入或使用键盘。在写入固件时,不要拔下键盘插头或以其他方式中断刷新过程,这一点非常重要。 + +不同的键盘有不同的方式进入这种特殊模式。如果您的键盘当前运行的是QMK或TMK,而您没有得到特定的指示,请按顺序尝试以下操作: + +* 按住两个shift键并按 `Pause` +* 按住两个shift键并按 `B` +* 拔下键盘插头, 同时按住空格键和 `B` , 插上键盘然后等一会再放开按键 +* 按下PCB底部的 `RESET` 物理键 +* 找到PCB上标记有 `BOOT0` 或 `RESET`的金属点, 在插入PCB的同时短接它们 + +成功后,您将在QMK工具箱中看到类似以下内容的消息: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +``` + +### 刷新你的键盘 + +单击QMK工具箱中的 `Flash` 按钮。您将看到类似以下内容的输出: + +``` +*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390 +*** DFU device connected +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset + +*** DFU device disconnected +*** Clueboard - Clueboard 66% HotSwap connected -- 0xC1ED:0x2390 +``` + +## 使用命令行刷新键盘 + +首先,您需要知道您的键盘使用的是哪个bootloader。通常是以下四个常见的bootloader。Pro-Micro 和 clones 使用 CATERINA, Teensy 使用 Halfkay, OLKB 键盘使用 QMK-DFU, 其他的atmega32u4芯片使用DFU。 + +您可以在以下文章中了解更多关于bootloader[刷新指令和Bootloader信息](flashing.md)。 + +如果您知道正在使用的bootloader是哪种,那么在编译固件时,可以向“make”命令里添加一些额外参数,以自动执行刷新过程。 + +### DFU + +对于DFU引导加载程序,当您准备好编译和刷新固件时,打开终端窗口并运行构建命令: + + make ::dfu + +例如,如果您的布局名为“xyverz”,并且您正在为rev5 planck构建一个布局,那么您可以使用此命令: + + make planck/rev5:xyverz:dfu + +编译完成后,应输出以下内容: + +``` +Linking: .build/planck_rev5_xyverz.elf [OK] +Creating load file for flashing: .build/planck_rev5_xyverz.hex [OK] +Copying planck_rev5_xyverz.hex to qmk_firmware folder [OK] +Checking file size of planck_rev5_xyverz.hex + * File size is fine - 18574/28672 + ``` + +到了这个时候, 构建脚本将每隔5秒查找一次DFU。它将重复以下操作,直到找到设备或将其取消。 + + dfu-programmer: no device present. + Error: Bootloader not found. Trying again in 5s. + +一旦出现以上回显,您将需要重置控制器。然后,它应该显示与以下类似的输出: + +``` +*** Attempting to flash, please don't remove device +>>> dfu-programmer atmega32u4 erase --force + Erasing flash... Success + Checking memory from 0x0 to 0x6FFF... Empty. +>>> dfu-programmer atmega32u4 flash /Users/skully/qmk_firmware/clueboard_66_hotswap_gen1_skully.hex + Checking memory from 0x0 to 0x55FF... Empty. + 0% 100% Programming 0x5600 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + 0% 100% Reading 0x7000 bytes... + [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success + Validating... Success + 0x5600 bytes written into 0x7000 bytes memory (76.79%). +>>> dfu-programmer atmega32u4 reset +``` + +如果您对此有任何问题,您可能需要这样做: + + sudo make ::dfu + +#### DFU命令 + +有许多DFU命令可用于将固件下载到DFU设备: + +* `:dfu` - 这是正常选项,等待DFU设备可用,然后刷新固件。这将每隔5秒检查一次,以查看是否出现了DFU设备。 +* `:dfu-ee` - 这将刷新一个`eep`文件,而不是普通的十六进制文件。这很不常见。 +* `:dfu-split-left` - 这将刷新正常固件,就像默认选项 (`:dfu`)一样. 但是,这也会刷新“左侧”EEPROM文件,用于分割键盘。 _这是基于Elite C的键盘的推荐选择。_ +* `:dfu-split-right` - 这将刷新正常固件,就像默认选项(`:dfu`). 但是,这也会刷新“右侧”EEPROM文件,用于分割键盘。 _这是基于Elite C的键盘的推荐选择。_ + + +### Caterina + +对于Arduino板以及其克隆版来说(比如SparkFun和ProMicro), 准备好编译和刷新固件后,打开终端窗口并运行构建命令: + + make ::avrdude + +比如, 你的布局叫"xyverz"你要创建一个rev2 Lets Split的布局,你要用以下命令: + + make lets_split/rev2:xyverz:avrdude + +固件完成编译后,它将输出类似以下的内容: + +``` +Linking: .build/lets_split_rev2_xyverz.elf [OK] +Creating load file for flashing: .build/lets_split_rev2_xyverz.hex [OK] +Checking file size of lets_split_rev2_xyverz.hex [OK] + * File size is fine - 27938/28672 +Detecting USB port, reset your controller now.............. +``` + +此时,复位,然后脚本将检测bootloader,然后刷新固件。输出应该像这样: + +``` +Detected controller on USB port at /dev/ttyS15 + +Connecting to programmer: . +Found programmer: Id = "CATERIN"; type = S + Software Version = 1.0; No Hardware Version given. +Programmer supports auto addr increment. +Programmer supports buffered memory access with buffersize=128 bytes. + +Programmer supports the following devices: + Device code: 0x44 + +avrdude.exe: AVR device initialized and ready to accept instructions + +Reading | ################################################## | 100% 0.00s + +avrdude.exe: Device signature = 0x1e9587 (probably m32u4) +avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed + To disable this feature, specify the -D option. +avrdude.exe: erasing chip +avrdude.exe: reading input file "./.build/lets_split_rev2_xyverz.hex" +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: writing flash (27938 bytes): + +Writing | ################################################## | 100% 2.40s + +avrdude.exe: 27938 bytes of flash written +avrdude.exe: verifying flash memory against ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: load data flash data from input file ./.build/lets_split_rev2_xyverz.hex: +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex auto detected as Intel Hex +avrdude.exe: input file ./.build/lets_split_rev2_xyverz.hex contains 27938 bytes +avrdude.exe: reading on-chip flash data: + +Reading | ################################################## | 100% 0.43s + +avrdude.exe: verifying ... +avrdude.exe: 27938 bytes of flash verified + +avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:FF) + +avrdude.exe done. Thank you. +``` +如果您对此有任何问题,您可能需要这样做: + + sudo make ::avrdude + + +此外,如果要刷新多个板,请使用以下命令: + + make ::avrdude-loop + +当你完成了刷新后,你需要按下ctrl+c或者其他正确的按键来让你的操作系统终止循环。 + + +## HalfKay + +对于PJRC设备(Teensy),当您准备好编译和刷新固件时,打开终端窗口并运行构建命令: + + make ::teensy + +比如, 如果你的布局叫做"xyverz"你想创建Ergodox or Ergodox EZ的布局,你要使用以下命令: + + make erdogox_ez:xyverz:teensy + +固件完成编译后,它将输出如下内容: + +``` +Linking: .build/ergodox_ez_xyverz.elf [OK] +Creating load file for flashing: .build/ergodox_ez_xyverz.hex [OK] +Checking file size of ergodox_ez_xyverz.hex [OK] + * File size is fine - 25584/32256 + Teensy Loader, Command Line, Version 2.1 +Read "./.build/ergodox_ez_xyverz.hex": 25584 bytes, 79.3% usage +Waiting for Teensy device... + (hint: press the reset button) + ``` + +此时,复位键盘。完成后,您将看到如下输出: + + ``` + Found HalfKay Bootloader +Read "./.build/ergodox_ez_xyverz.hex": 28532 bytes, 88.5% usage +Programming............................................................................................................................................................................ +................................................... +Booting +``` + +## STM32 (ARM) + +对于大多数ARM板(包括Proton C、Planck Rev 6和Preonic Rev 3),当您准备好编译和刷新固件时,打开终端窗口并运行构建命令: + + make ::dfu-util + +例如,如果您的keymap被命名为“xyverz”,并且您正在为Planck Revision 6键盘构建一个布局,那么您需要使用以下命令,然后将键盘重新启动到bootloader(在完成编译之前): + + make planck/rev6:xyverz:dfu-util + +固件完成编译后,它将输出如下内容: + +``` +Linking: .build/planck_rev6_xyverz.elf [OK] +Creating binary load file for flashing: .build/planck_rev6_xyverz.bin [OK] +Creating load file for flashing: .build/planck_rev6_xyverz.hex [OK] + +Size after: + text data bss dec hex filename + 0 41820 0 41820 a35c .build/planck_rev6_xyverz.hex + +Copying planck_rev6_xyverz.bin to qmk_firmware folder [OK] +dfu-util 0.9 + +Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. +Copyright 2010-2016 Tormod Volden and Stefan Schmidt +This program is Free Software and has ABSOLUTELY NO WARRANTY +Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ + +Invalid DFU suffix signature +A valid DFU suffix will be required in a future dfu-util release!!! +Opening DFU capable USB device... +ID 0483:df11 +Run-time device DFU version 011a +Claiming USB DFU Interface... +Setting Alternate Setting #0 ... +Determining device status: state = dfuERROR, status = 10 +dfuERROR, clearing status +Determining device status: state = dfuIDLE, status = 0 +dfuIDLE, continuing +DFU mode device DFU version 011a +Device returned transfer size 2048 +DfuSe interface name: "Internal Flash " +Downloading to address = 0x08000000, size = 41824 +Download [=========================] 100% 41824 bytes +Download done. +File downloaded successfully +Transitioning to dfuMANIFEST state +``` + +## 试一试吧! + +恭喜您! 您的自定义固件已经刷写到您的键盘 + +试一试,确保一切按你想的方式进行。我们写了[测试和调试](newbs_testing_debugging.md)来完善新手引导。 因此,请前往那里了解如何排除自定义功能的故障。 diff --git a/zh-cn/newbs_getting_started.md b/zh-cn/newbs_getting_started.md new file mode 100644 index 00000000000..4e7850201d1 --- /dev/null +++ b/zh-cn/newbs_getting_started.md @@ -0,0 +1,102 @@ +# 介绍 + +你的电脑键盘里面包含一个处理器, 这个处理器和你电脑里面的不太一样。这个处理器负责运行一些特殊的软件,这些软件可以监测按钮按下并将按钮处于按下还是释放状态的数据发送出去。QMK就是这样一种软件,即监测按钮被按下并发送这样的信息到作为主机的计算机上。当你创建了你的布局, 你也就创建了你的键盘运行的的可执行程序。 + +QMK试图通过使简单的事情变得更简单,使使不可能成为可能来把大量的权力交给你。你不需要懂如何通过程序创建强大的布局——你只需要遵循简单的语法规则。 + +# 新手上路 + +在你能创建布局前,你要安装一些软件来建立你的开发环境。无论你想编译多少固件,这个操作都只需要进行一次。 + +如果您更喜欢图形化界面, 请考虑使用在线工具[QMK配置器](https://config.qmk.fm)。 请参考 [使用在线GUI构建您的第一个固件](newbs_building_firmware_configurator.md)。 + + +## 下载软件 + +### 文本编辑器 + +你需要一个可以编辑 **纯文本** 文件的程序。在Windows上你可以用Notepad, 在Linux上使用gedit,这两个都是简单又实用的文本编辑工具。 在macOS上, 请小心使用 “文本编辑” 这个默认软件: 如果你不明确的选择_格式_菜单中的 _制作纯文本_ 的话文本将不会被保存为纯文本。 + +你也可以下载并安装一个专用编辑器 [Sublime Text](https://www.sublimetext.com/) 或 [VS Code](https://code.visualstudio.com/)。 这大概是跨平台的最好方法了, 这些编辑器是专门为了编辑代码设计的。 + +?>搞不清用哪种编辑器? Laurence Bradford 写了篇关于编辑器选择的文章 [a great introduction](https://learntocodewith.me/programming/basics/text-editors/)。 + +### QMK 工具箱 + +QMK 工具箱 是一种可选的Windows和macOS下的图形化工具,它可以对你的定制键盘进行编程和调试。你可能会发现它就是你能简单的刷新你的键盘固件并查看调试信息的稀世珍宝。 + +[在这里下载最新发布版本](https://github.com/qmk/qmk_toolbox/releases/latest) + +* Windows用户: `qmk_toolbox.exe` (绿色版) 或 `qmk_toolbox_install.exe` (安装版) +* macOS用户: `QMK.Toolbox.app.zip` (绿色版) or `QMK.Toolbox.pkg` (安装版) + +## 建立你的环境 + +我们为了使QMK环境变得更容易建立已竭尽所能。你只需要准备Linux 或 Unix 环境, 然后让QMK安装剩余部分。 + +?> 如果你从未使用过Linux/Unix的命令行,有一些你需要学习的基础概念和命令,以下资料将教会您使用QMK环境的必要能力:
+[必会Linux命令](https://www.guru99.com/must-know-linux-commands.html)
+[一些基本的Unix命令](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) + +### Windows + +你需要安装MSYS2和Git. + +* 按照以下安装说明进行操作[MSYS2 主页](http://www.msys2.org)。 +* 关闭所有打开的MSYS2终端并打开新的MSYS2 MinGW 64-bit终端。 +* 使用以下命令安装Git: `pacman -S git`。 + +### macOS + +你需要安装Homebrew。按照以下说明进行操作 [Homebrew 主页](https://brew.sh)。 + +在Homebrew安装完成后, 继续 _同步QMK工程_. 这一步你将会通过运行一个脚本安装其他包。 + +### Linux + +你将需要安装Git.你很有可能已经安装,但若你尚未安装,可以使用以下命令进行安装: + +* Debian / Ubuntu / Devuan: `apt-get install git` +* Fedora / Red Hat / CentOS: `yum install git` +* Arch: `pacman -S git` + +?> 无论你使用哪种平台,Docker都可以是你的选择[点这里进一步了解](getting_started_build_tools.md#docker) + +## 同步QMK工程 + +当你建立Linux/Unix环境后,你就已经可以下载QMK了.下载时我们可以用Git来 "clone" QMK仓库. 打开一个终端或MSYS2 MinGW 窗口,在阅读剩余的指南时请保持窗口打开。在窗口里面运行以下两句命令: + +```shell +git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git +cd qmk_firmware +``` + +?> 如果您已经知道[如何使用GitHub](getting_started_github.md), 我们推荐您创建您自己的分支并克隆。 如果您不知道这是什么, 您完全可以忽略这句无关紧要的话。 + +QMK附带一个脚本,可帮助您设置剩余的所需内容.您可以通过输入此命令来运行它: + + util/qmk_install.sh + +## 测试你的开发环境 + +现在你的QMK环境已经建立完毕, 你可以为你的键盘创建固件了。开始试着创建键盘的默认固件吧。 你需要使用以下格式的命令创建固件: + + make :default + +比如, 制作一个Clueboard 66%的固件,需要用: + + make clueboard/66/rev3:default + +当完成后你要看到一些回显,尾部如下: + +``` +Linking: .build/clueboard_66_rev3_default.elf [OK] +Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] +Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] +Checking file size of clueboard_66_rev3_default.hex [OK] + * The firmware size is fine - 26356/28672 (2316 bytes free) +``` + +# 创建你的布局 + +现在你可以创建属于你自己的布局了! 请移步 [构建你的第一个固件](newbs_building_firmware.md)来继续。 diff --git a/zh-cn/newbs_learn_more_resources.md b/zh-cn/newbs_learn_more_resources.md new file mode 100644 index 00000000000..ccb4fa326c4 --- /dev/null +++ b/zh-cn/newbs_learn_more_resources.md @@ -0,0 +1,15 @@ +# 学习资源 + +这些资源旨在让QMK社区的新成员更了解新成员文档中提供的信息。 + +Git 资源: + +* [很好的通用教程](https://www.codecademy.com/learn/learn-git) +* [从例子中学习Git游戏](https://learngitbranching.js.org/) +* [了解有关GitHub的更多信息的Git资源](getting_started_github.md) +* [专门针对QMK的Git资源](contributing.md) + + +命令行资源: + +* [超棒的命令行通用教程](https://www.codecademy.com/learn/learn-the-command-line) diff --git a/zh-cn/newbs_testing_debugging.md b/zh-cn/newbs_testing_debugging.md new file mode 100644 index 00000000000..4edceee41a0 --- /dev/null +++ b/zh-cn/newbs_testing_debugging.md @@ -0,0 +1,44 @@ +# 测试和调试 + +使用自定义固件刷新键盘后,您就可以测试它了。如果您幸运,一切都会完美运行,但如果没有,这份文件将帮助您找出问题所在。 + +## 测试 + +测试键盘通常非常简单。按下每一个键并确保它发送的是您期望的键。甚至有一些程序可以帮助您确保没有任何键失效。 + +注意:这些程序不是由QMK提供或认可的。 + +* [QMK Configurator](https://config.qmk.fm/#/test/) (网页版) +* [Switch Hitter](https://web.archive.org/web/20190413233743/https://elitekeyboards.com/switchhitter.php) (仅Windows) +* [Keyboard Viewer](https://www.imore.com/how-use-keyboard-viewer-your-mac) (仅Mac) +* [Keyboard Tester](http://www.keyboardtester.com) (网页版) +* [Keyboard Checker](http://keyboardchecker.com) (网页版) + +## 使用QMK工具箱进行调试 + +[QMK工具箱](https://github.com/qmk/qmk_toolbox) 将会在你的`rules.mk`中有`CONSOLE_ENABLE = yes`的时候显示你键盘发来的消息。 默认情况下,输出极为有限,不过您可以打开调试模式来增加输出信息量。使用你键盘布局中的`DEBUG`键码,使用 [命令](feature_command.md) 特性来使能调试模式, 或者向你的布局中添加以下代码。 + +```c +void keyboard_post_init_user(void) { + // Customise these values to desired behaviour + debug_enable=true; + debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; +} +``` + + + +## 发送您自己的调试消息 + +有时用[custom code](custom_quantum_functions.md)发送自定义调试信息很有用. 这么做很简单. 首先在你文件头部包含`print.h`: + + #include + +之后,您可以使用一些不同的打印功能: + +* `print("string")`: 打印简单字符串. +* `uprintf("%s string", var)`: 打印格式化字符串 +* `dprint("string")`: 仅在调试模式使能时打印简单字符串 +* `dprintf("%s string", var)`: 仅在调试模式使能时打印格式化字符串 diff --git a/zh-cn/reference_glossary.md b/zh-cn/reference_glossary.md new file mode 100644 index 00000000000..0e0521221cd --- /dev/null +++ b/zh-cn/reference_glossary.md @@ -0,0 +1,167 @@ +# QMK术语表 + +## ARM +多家公司生产的32位单片机系列,例如Atmel, Cypress, Kinetis, NXP, ST, 和 TI等公司。 + +## AVR +[Atmel](http://www.microchip.com/)公司的单片机系列。 AVR是TMK的初始支持平台。 + +## AZERTY +Français (法国)标准键盘布局。用键盘的前六个字母命名。 + +## Backlight(背光) +键盘上照明的通称。背光通常是一组LED灯,通过键帽或者按轴发光,但也不总是这样。 + +## Bluetooth(蓝牙) +一种短距离点对点无线协议。许多多无线键盘使用此协议。 + +## Bootloader(引导加载程序) +一种写到你单片机的保护区的特殊的程序,该程序可以使单片机升级自己的固件,通常是通过USB来升级。 + +## Bootmagic(热改键) +允许各种键盘行为动态变化的功能,如交换或禁用常用键。 + +## C +一种适用于系统代码的低级编程语言。大多数qmk代码是用C编写的。 + +## Colemak +一种流行的键盘布局。 + +## Compile(编译) +把人可读的代码转换成你的单片机可以运行的机器代码的过程。 + +## Dvorak +一个由August Dvorak博士在20世纪30年代创建的布局。Dvorak简化键盘(Dvorak Simplified Keyboard)的缩写。 + +## Dynamic Macro(动态宏) +一种记录在键盘上的宏,当键盘拔出或计算机重新启动时,宏将丢失。 + +* [动态宏文档](feature_dynamic_macros.md) + +## Eclipse +是一种受C语言开发者追捧的集成开发环境(IDE)。 + +* [Eclipse安装说明](eclipse.md) + +## Firmware(固件) +用来控制单片机的软件。 + +## git +命令行版本控制软件 + +## GitHub +负责大多数QMK项目的网站。它是Git、问题跟踪和其他帮助我们运行qmk的功能的集成平台。 + +## ISP(在系统编程) +在系统编程(In-system programming), 使用外部硬件和JTAG管脚对AVR芯片进行编程的一种方法。 + +## hid_listen +从键盘接收调试消息的接口。 您可以使用[QMK Flasher](https://github.com/qmk/qmk_flasher)或[PJRC's hid_listen](https://www.pjrc.com/teensy/hid_listen.html)查看这些消息 + +## Keycode(键码) +表示特定键的2字节数据。`0x00`-`0xFF`用于[基本键码](keycodes_basic.md)而`0x100`-`0xFFFF`用于[量子键码](quantum_keycodes.md). + +## Key Down +一个键按下尚未抬起时触发的事件。 + +## Key Up +一个键抬起时触发的事件。 + +## Keymap(键映射) +映射到物理键盘布局的一组键码,在按键和按键释放时进行处理。有时翻译为布局,意为软件上表示的布局,即映射。 + +## Layer(层) +为了让一个键实现多个功能的抽象结构。最高活动层有限。 + +## Leader Key(前导键、设置菜单键) +本功能允许您点击前导键,然后按顺序按1-3个键子来激活按键或其他量子功能。 + +* [前导键文档](feature_leader_key.md) + +## LED +发光二极管,键盘上最常用的指示灯装置。 + +## Make +用于编译所有源文件的软件包。可以使用`make`命令和其他参数来编译你的固件。 + +## Matrix(矩阵) +一种由列和行组成的接线模式,使单片机能够用较少的引脚检测按键。矩阵通常包含二极管,以达到全键无冲。 + +## Macro(宏) +本功能可以在敲击单个键后发送多个按键事件(hid报告)。 + +* [宏文档](feature_macros.md) + +## MCU(单片机、微控制单元) +微控制单元,键盘的处理器。 + +## Modifier(修改键、修饰键、功能键) +按住该键将会改变其他键的功能,修饰键包括 Ctrl, Alt, 和 Shift。 + +## Mousekeys(鼠标键) +本功能在您敲击键盘时会控制鼠标光标。 + +* [鼠标键文档](feature_mouse_keys.md) + +## N-Key Rollover (NKRO、全键无冲) +一种术语,适用于能够同时报告任意数量按键的键盘。 + +## Oneshot Modifier(粘滞键) +一种能让你的功能键一直保持按下,直到你按下其他键的功能。它叫做粘滞键或叫做粘连键,该功能由软件实现而非机械结构。 + +## ProMicro +一种低成本AVR开发板。这种板子很容易在购物网站找到(价格不到20RMB),但是据说刷写pro micro有点令人抓狂。 + +## Pull Request(拉请求、PR) +向QMK请求提交代码。我们鼓励所有用户提交你们自己的键盘的代码。 + +## QWERTY +标准英文键盘,通常也用于其他语言,例如中文。是用键盘前6个字母命名的。 + +## QWERTZ +标准Deutsche(德语)键盘布局。使用前6个字母明名。 + +## Rollover(允许翻转、无冲形式) +该术语表示在一个键已按下时按下另一个键。形式包括2KRO(双键无冲),6KRO(6键无冲),和NKRO(全键无冲),无冲表示可同时按下而不产生冲突的键的数量。 + +## Scancode(扫描码) +HID报告中的一个1字节的数字,表示一个键子。这些数字在下列文档中[HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf)该文档发布于[USB-IF](http://www.usb.org/)。 + +## Space Cadet键盘的shift键 +一种特使的shift设置,能让你通过敲击左或右shift一次或多次键入不同的括号。 + +* [Space Cadet键盘文档](feature_space_cadet.md) + +## Tap(敲击、单击) +按下并释放一个键。在某些情况下您需要区分键按下和键抬起,但是单击把两个事件都包括了。 + +## Tap Dance(多击键) +本功能允许向同一个键子分配多个键码,并根据按键次数区分。 + +* [多击键文档](feature_tap_dance.md) + +## Teensy +一种低成本AVR开发板,通常用于手工连线键盘。这个teensy是有点小贵但是halfkay bootloader会让它刷写十分简单,所以也很常用。 + +## Underlight(背光) +用于照亮电路板底面的LED的总称。这些LED通常从印刷电路板的底部向键盘所在的表面发光。 + +## Unicode +在较大的计算机世界中,Unicode是一组编码方案,用于表示任何语言中的字符。 与qmk相关的是,它意味着使用各种操作系统方案来发送Unicode代码点,而不是扫描码。 + +* [Unicode文档](feature_unicode.md) + +## Unit Testing(单元测试) +针对qmk的自动运行测试框架。单元测试帮助我们确信我们的更改不会破坏任何东西。 + +* [单元测试文档](unit_testing.md) + +## USB +通用串行总线,键盘最常见的有线接口。 + +## USB 主机 (或简易主机) +USB诸暨市你的电脑,或者你的键盘所插的任何设备。 + +# 并没有找到你想找到的术语? + +[建立一个issue](https://github.com/qmk/qmk_firmware/issues) ,想好你的问题,或许你所问的术语就会添加到这里。创建一个PR帮我们添加需要添加的术语当然坠吼了:)