summaryrefslogtreecommitdiff
path: root/docs/zh-cn
diff options
context:
space:
mode:
Diffstat (limited to 'docs/zh-cn')
-rw-r--r--docs/zh-cn/README.md45
-rw-r--r--docs/zh-cn/_summary.md322
-rw-r--r--docs/zh-cn/api_docs.md73
-rw-r--r--docs/zh-cn/api_overview.md20
-rw-r--r--docs/zh-cn/cli.md43
-rw-r--r--docs/zh-cn/cli_commands.md503
-rw-r--r--docs/zh-cn/cli_configuration.md126
-rw-r--r--docs/zh-cn/cli_tab_complete.md32
-rw-r--r--docs/zh-cn/configurator_architecture.md66
-rw-r--r--docs/zh-cn/configurator_default_keymaps.md198
-rw-r--r--docs/zh-cn/configurator_step_by_step.md63
-rw-r--r--docs/zh-cn/configurator_troubleshooting.md31
-rw-r--r--docs/zh-cn/contributing.md188
-rw-r--r--docs/zh-cn/custom_quantum_functions.md367
-rw-r--r--docs/zh-cn/driver_installation_zadig.md102
-rw-r--r--docs/zh-cn/easy_maker.md37
-rw-r--r--docs/zh-cn/faq.md6
-rw-r--r--docs/zh-cn/faq_build.md127
-rw-r--r--docs/zh-cn/faq_debug.md188
-rw-r--r--docs/zh-cn/faq_general.md59
-rw-r--r--docs/zh-cn/faq_keymap.md172
-rw-r--r--docs/zh-cn/faq_misc.md108
-rw-r--r--docs/zh-cn/feature_grave_esc.md39
-rw-r--r--docs/zh-cn/feature_space_cadet.md70
-rw-r--r--docs/zh-cn/flashing.md329
-rw-r--r--docs/zh-cn/flashing_bootloadhid.md75
-rw-r--r--docs/zh-cn/getting_started_docker.md59
-rw-r--r--docs/zh-cn/getting_started_getting_help.md15
-rw-r--r--docs/zh-cn/getting_started_github.md7
-rw-r--r--docs/zh-cn/getting_started_introduction.md9
-rw-r--r--docs/zh-cn/getting_started_vagrant.md61
-rw-r--r--docs/zh-cn/keymap.md209
-rw-r--r--docs/zh-cn/mod_tap.md143
-rw-r--r--docs/zh-cn/newbs.md36
-rw-r--r--docs/zh-cn/newbs_best_practices.md163
-rw-r--r--docs/zh-cn/newbs_building_firmware.md87
-rw-r--r--docs/zh-cn/newbs_building_firmware_configurator.md18
-rw-r--r--docs/zh-cn/newbs_flashing.md317
-rw-r--r--docs/zh-cn/newbs_getting_started.md210
-rw-r--r--docs/zh-cn/newbs_learn_more_resources.md36
-rw-r--r--docs/zh-cn/newbs_testing_debugging.md46
-rw-r--r--docs/zh-cn/reference_configurator_support.md200
-rw-r--r--docs/zh-cn/reference_glossary.md81
-rw-r--r--docs/zh-cn/support.md22
-rw-r--r--docs/zh-cn/syllabus.md77
-rw-r--r--docs/zh-cn/translating.md60
-rw-r--r--docs/zh-cn/zh_cn_doc_status.sh35
47 files changed, 3932 insertions, 1348 deletions
diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md
index b42818d582..93dfbf1eef 100644
--- a/docs/zh-cn/README.md
+++ b/docs/zh-cn/README.md
@@ -1,31 +1,42 @@
-# QMK机械键盘固件
+# Quantum Mechanical Keyboard固件
-[![当前版本](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags)
-[![异议](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/)
+<!---
+ original document: 0.15.12:docs/README.md
+ git diff 0.15.12 HEAD -- docs/README.md | cat
+-->
## 什么是 QMK 固件?
-QMK (*Quantum Mechanical Keyboard*) 是一个社区维护的开源软件,包括 QMK 固件, QMK 工具箱, qmk.fm网站, 和这些文档。QMK 固件是一个基于[tmk\_keyboard](https://github.com/tmk/tmk_keyboard)的键盘固件,它在爱特梅尔AVR微控制器实现一些有用的功能,确切地说, 是在 [OLKB product line](https://olkb.com), 在 [ErgoDox EZ](https://www.ergodox-ez.com) 键盘, 和 [Clueboard product line](https://clueboard.co/). 上。它被移植到使用ChibiOS的ARM芯片上. 它可以在飞线键盘或定制PCB键盘中发挥功能.
+QMK (*Quantum Mechanical Keyboard*) 是一个社区维护的用于开发计算机输入设备的开源软件。社区专注像键盘,鼠标,MIDI设备的各种电子输入设备。社区内的核心小组成员维护[QMK固件](https://github.com/qmk/qmk_firmware),[QMK配置器](https://config.qmk.fm)(QMK Configurator),[QMK工具箱](https://github.com/qmk/qmk_toolbox)(QMK Toolbox),[qmk.fm](https://qmk.fm),并与各位社区成员维护这份文档。
-## 如何得到它
+## 如何入门
-如果你打算贡献布局, 键盘, 或者其他QMK特性, 一下是最简单的方法:[从GitHub获得repo分支](https://github.com/qmk/qmk_firmware#fork-destination-box), 并克隆你的repo到本地进行编辑,推送,然后从你的分支打开 [Pull Request](https://github.com/qmk/qmk_firmware/pulls).
+<div class="flex-container">
-此外, 你也可以直接下载 ([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`).
+?> **基础方式** [QMK配置器](zh-cn/newbs_building_firmware_configurator.md) <br>
+用户友好的图形界面工具,无需具备编程知识基础。
-## 如何编译
+?> **进阶方式** [基于源代码](zh-cn/newbs.md) <br>
+功能更强大,但门槛较高。
-在你能编译之前, 你需要[部署环境](zh-cn/getting_started_build_tools.md) 用于 AVR or/and ARM 开发。完成后, 你可以使用 `make` 命令来编译一个键盘和布局使用以下命令:
+</div>
- make planck/rev4:default
+## 个性化定制
-这将建立 `planck`的`rev4` 修订版本并使用 `default`布局。并非所有键盘都有修订版本 (也叫做子项目或文件夹),在此情况下,修订版本可以省略,如下:
+QMK提供了很多功能,对应着很多可供浏览的配套文档。大部分功能都是通过修改[键映射](zh-cn/keymap.md)及[键码](zh-cn/keycodes.md)实现的。
- make preonic:default
+## 需要帮助?
-## 如何定制
+请查阅[寻求帮助页面](zh-cn/support.md)以了解如何获取QMK使用方法的帮助。
-QMK 有许多 [特性](zh-cn/features.md)来探索,也有很多 [参考文档](https://docs.qmk.fm) 供您发掘。你可以通过修改 [布局](zh-cn/keymap.md)和[键码](zh-cn/keycodes.md)来利用许多特性。
+## 回馈社区
+
+有多种回馈社区的方法,最简单的方法是开始使用QMK并向你的朋友们推荐它。
+
+* 可以在我们的论坛及聊天室进行互助:
+ * [/r/olkb](https://www.reddit.com/r/olkb/)
+ * [Discord服务器](https://discord.gg/Uq7gcHh)
+* 点击页面下方的“Edit This Page”,可以对文档提供贡献。
+* [将这份文档翻译为你的语言](zh-cn/translating.md)
+* [上报bug](https://github.com/qmk/qmk_firmware/issues/new/choose)
+* [发起Pull Request](zh-cn/contributing.md)
diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md
index cedcfbd525..8a710a9ec1 100644
--- a/docs/zh-cn/_summary.md
+++ b/docs/zh-cn/_summary.md
@@ -1,133 +1,193 @@
-* [完全菜鸟指南](zh-cn/newbs.md)
+<!--for translators, see first: zh-cn/reference_glossary.md#terms-of-zh-cn-translate -->
+* 新手教程
+ * [介绍](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/newbs_building_firmware.md)
+ * [刷写固件](zh-cn/newbs_flashing.md)
+ * [寻求帮助](zh-cn/support.md)
+ * [其它资源](zh-cn/newbs_learn_more_resources.md)
+ * [QMK大纲](zh-cn/syllabus.md)
+
+* FAQ
+ * [常规FAQ](zh-cn/faq_general.md)
+ * [构建/编译QMK](zh-cn/faq_build.md)
+ * [QMK问题排查](zh-cn/faq_misc.md)
+ * [调试QMK](zh-cn/faq_debug.md)
+ * [键映射FAQ](zh-cn/faq_keymap.md)
+ * [充分利用AVR的存储空间](zh-cn/squeezing_avr.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)
-<!--fromen:20200126-6:03AM(GMT+8)-->
-<!--cn:20200211-11:04AM(GMT+8)-->
+
+* 配置器(Configurator)
+ * [总览](zh-cn/newbs_building_firmware_configurator.md)
+ * [入门](zh-cn/configurator_step_by_step.md)
+ * [问题排查](zh-cn/configurator_troubleshooting.md)
+ * [框架](zh-cn/configurator_architecture.md)
+ * QMK API
+ * [总览](zh-cn/api_overview.md)
+ * [API文档](zh-cn/api_docs.md)
+ * [键盘支持](zh-cn/reference_configurator_support.md)
+ * [添加默认键映射](zh-cn/configurator_default_keymaps.md)
+
+* CLI
+ * [总览](zh-cn/cli.md)
+ * [配置](zh-cn/cli_configuration.md)
+ * [命令](zh-cn/cli_commands.md)
+ * [Tab补全](zh-cn/cli_tab_complete.md)
+
+* 使用QMK
+ * 导览
+ * [功能定制](zh-cn/custom_quantum_functions.md)
+ * [利用Zadig安装驱动](zh-cn/driver_installation_zadig.md)
+ * [极简式制作](zh-cn/easy_maker.md)
+ * [键映射总览](zh-cn/keymap.md)
+ * 开发环境
+ * [Docker指南](zh-cn/getting_started_docker.md)
+ * [Vagrant指南](zh-cn/getting_started_vagrant.md)
+ * 刷写(Flashing)
+ * [刷写](zh-cn/flashing.md)
+ * [刷写ATmega32A (ps2avrgb)](zh-cn/flashing_bootloadhid.md)
+ * IDE
+ * [在Eclipse中使用QMK](zh-cn/other_eclipse.md)
+ * [在VSCode中使用QMK](zh-cn/other_vscode.md)
+ * Git最佳实践
+ * [介绍](zh-cn/newbs_git_best_practices.md)
+ * [你自己的副本](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/hand_wire.md)
+ * [ISP刷写指南](zh-cn/isp_flashing_guide.md)
+
+ * 键码入门
+ * [键码汇总](zh-cn/keycodes.md)
+ * [基础键码](zh-cn/keycodes_basic.md)
+ * [语言特定的键码](zh-cn/reference_keymap_extras.md)
+ * [修饰键](zh-cn/feature_advanced_keycodes.md)
+ * [原子键码](zh-cn/quantum_keycodes.md)
+ * [Magic键码](zh-cn/keycodes_magic.md)
+
+ * 键码进阶
+ * [指令](zh-cn/feature_command.md)
+ * [动态宏](zh-cn/feature_dynamic_macros.md)
+ * [Grave Escape](zh-cn/feature_grave_esc.md)
+ * [前导键](zh-cn/feature_leader_key.md)
+ * [Mod-Tap](zh-cn/mod_tap.md)
+ * [宏](zh-cn/feature_macros.md)
+ * [鼠标键](zh-cn/feature_mouse_keys.md)
+ * [Space Cadet Shift](zh-cn/feature_space_cadet.md)
+ * [US ANSI上档键值](zh-cn/keycodes_us_ansi_shifted.md)
+
+ * 软件特性
+ * [自动Shift](zh-cn/feature_auto_shift.md)
+ * [组合键](zh-cn/feature_combo.md)
+ * [防抖API](zh-cn/feature_debounce_type.md)
+ * [按键锁定](zh-cn/feature_key_lock.md)
+ * [按键重定义](zh-cn/feature_key_overrides.md)
+ * [层](zh-cn/feature_layers.md)
+ * [粘滞键](zh-cn/one_shot_keys.md)
+ * [光标设备](zh-cn/feature_pointing_device.md)
+ * [原生HID](zh-cn/feature_rawhid.md)
+ * [Sequencer](zh-cn/feature_sequencer.md)
+ * [换手](zh-cn/feature_swap_hands.md)
+ * [一键多用](zh-cn/feature_tap_dance.md)
+ * [点按配置](zh-cn/tap_hold.md)
+ * [终端](zh-cn/feature_terminal.md)
+ * [Unicode](zh-cn/feature_unicode.md)
+ * [用户空间](zh-cn/feature_userspace.md)
+ * [WPM计算](zh-cn/feature_wpm.md)
+
+ * 硬件特性
+ * 显示
+ * [HD44780 LCD控制器](zh-cn/feature_hd44780.md)
+ * [ST7565 LCD驱动](zh-cn/feature_st7565.md)
+ * [OLED驱动](zh-cn/feature_oled_driver.md)
+ * 灯效
+ * [背光](zh-cn/feature_backlight.md)
+ * [LED矩阵](zh-cn/feature_led_matrix.md)
+ * [RGB灯光](zh-cn/feature_rgblight.md)
+ * [RGB矩阵](zh-cn/feature_rgb_matrix.md)
+ * [音频](zh-cn/feature_audio.md)
+ * [蓝牙](zh-cn/feature_bluetooth.md)
+ * [Bootmagic Lite](zh-cn/feature_bootmagic.md)
+ * [自定义矩阵](zh-cn/custom_matrix.md)
+ * [Digitizer](zh-cn/feature_digitizer.md)
+ * [拨动开关(DIP Switch)](zh-cn/feature_dip_switch.md)
+ * [编码器(旋钮)](zh-cn/feature_encoders.md)
+ * [触摸反馈](zh-cn/feature_haptic_feedback.md)
+ * [摇杆](zh-cn/feature_joystick.md)
+ * [LED指示](zh-cn/feature_led_indicators.md)
+ * [MIDI](zh-cn/feature_midi.md)
+ * [Proton C转换](zh-cn/proton_c_conversion.md)
+ * [PS/2鼠标](zh-cn/feature_ps2_mouse.md)
+ * [分体式键盘](zh-cn/feature_split_keyboard.md)
+ * [速记](zh-cn/feature_stenography.md)
+ * [热敏打印机](zh-cn/feature_thermal_printer.md)
+ * [Velocikey](zh-cn/feature_velocikey.md)
+
+* QMK开发
+ * [PR Checklist](zh-cn/pr_checklist.md)
+ * 打破兼容的改动
+ * [总览](zh-cn/breaking_changes.md)
+ * [我的PR已打上标记](zh-cn/breaking_changes_instructions.md)
+ * [近期的变更日志(Changelog)](zh-cn/ChangeLog/20210529.md "QMK v0.13.0 - 2021 May 29")
+ * [更早期的不兼容改动](zh-cn/breaking_changes_history.md)
+
+ * C语言开发
+ * [ARM调试指引](zh-cn/arm_debugging.md)
+ * [AVR处理器](zh-cn/hardware_avr.md)
+ * [C编码规范](zh-cn/coding_conventions_c.md)
+ * [兼容的微处理器](zh-cn/compatible_microcontrollers.md)
+ * [驱动](zh-cn/hardware_drivers.md)
+ * [ADC驱动](zh-cn/adc_driver.md)
+ * [Audio驱动](zh-cn/audio_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)
+ * [串口驱动](zh-cn/serial_driver.md)
+ * [UART驱动](zh-cn/uart_driver.md)
+ * [操控GPIO](zh-cn/internals_gpio_control.md)
+ * [键盘开发指引](zh-cn/hardware_keyboard_guidelines.md)
+
+ * Python开发
+ * [编码规范](zh-cn/coding_conventions_python.md)
+ * [QMK CLI开发](zh-cn/cli_development.md)
+
+ * 配置器开发
+ * QMK API
+ * [开发环境](zh-cn/api_development_environment.md)
+ * [架构总览](zh-cn/api_development_overview.md)
+
+ * 硬件平台开发
+ * Arm/ChibiOS
+ * [选择MCU](zh-cn/platformdev_selecting_arm_mcu.md)
+ * [启动引导](zh-cn/platformdev_chibios_earlyinit.md)
+
+ * QMK参考信息
+ * [参与到QMK](zh-cn/contributing.md)
+ * [翻译QMK文档](zh-cn/translating.md)<!--but should we translate this? currently keep it fallback-->
+ * [配置](zh-cn/config_options.md)
+ * [数据驱动配置](zh-cn/data_driven_config.md)
+ * [Make指引](zh-cn/getting_started_make_guide.md)
+ * [编写文档的最佳实践](zh-cn/documentation_best_practices.md)
+ * [文档模板](zh-cn/documentation_templates.md)
+ * [贡献配列到社区](zh-cn/feature_layouts.md)
+ * [单元测试](zh-cn/unit_testing.md)
+ * [常用函数](zh-cn/ref_functions.md)
+ * [info.json参考资料](zh-cn/reference_info_json.md)
+
+ * 深入了解
+ * [键盘工作原理](zh-cn/how_keyboards_work.md)
+ * [键盘矩阵原理](zh-cn/how_a_matrix_works.md)
+ * [了解QMK](zh-cn/understanding_qmk.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)
+
+<!--fromen:20211014-12:00(GMT+8) commit 04cf161aa01fd433b5dae69d9fd31569ed5dca59-->
diff --git a/docs/zh-cn/api_docs.md b/docs/zh-cn/api_docs.md
new file mode 100644
index 0000000000..a2df9ec20a
--- /dev/null
+++ b/docs/zh-cn/api_docs.md
@@ -0,0 +1,73 @@
+# QMK API
+
+<!---
+ original document: 0.15.12:docs/api_docs.md
+ git diff 0.15.12 HEAD -- docs/api_docs.md | cat
+-->
+
+本章节详述了QMK API的使用方法,若您是应用开发者,使用这套API可以实现[QMK](https://qmk.fm)键盘固件的编译支持。
+
+## 总览
+
+本服务提供了一套用于编译自定义键映射的异步API,通过POST方式发送JSON参数到API,定期检查执行状态,待固件编译完成后,即可下载生成的固件文件和固件的源文件(如果需要的话)。
+
+#### 荷载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"]
+ ]
+}
+```
+
+如上可见,荷载参数里有用于生成固件文件的所有键盘信息。每一个层定义都包含了与键盘 `LAYOUT` 宏定义一致的QMK键码列表数据,若该键盘有多个支持的 `LAYOUT` 宏定义,也可以指定使用的是哪一个。
+
+## 提交一个编译job
+
+若要将键映射配置编译成固件文件,仅需将JSON参数通过POST发送至 `/v1/compile` 节点。下面的示例中我们假设JSON荷载参数已存放在 `json_data` 文件中。
+
+```
+$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" https://api.qmk.fm/v1/compile
+{
+ "enqueued": true,
+ "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6"
+}
+```
+
+## 检查状态
+
+键映射配置提交后,可以简单地通过 HTTP GET 请求来查询job状态:
+
+```
+$ curl https://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
+}
+```
+
+这份信息告诉我们编译job已经提交到队列中且正在执行。job的状态有5种:
+
+* **failed(失败)**: 编译服务出现问题。
+* **finished(完成)**: 编译已完成,`result` 字段中保存了编译结果。
+* **queued(排队中)**: 键映射job在等待可用的编译服务器。
+* **running(执行中)**: 编译进行中,应当很快就会结束。
+* **unknown(未知)**: 出现了较严重的错误,请给我们[提交一个bug](https://github.com/qmk/qmk_compiler/issues).
+
+## 确认编译产出
+
+编译job完成后请查看 `result` 字段,该字段下保存了如下信息项的哈希表数据:
+
+* `firmware_binary_url`: 用于刷写的固件文件URL列表
+* `firmware_keymap_url`: `keymap.c` 文件URL列表
+* `firmware_source_url`: 完整的固件源代码URL列表
+* `output`: 编译job的stdout及stderr输出信息,所有错误信息都会在这里。
diff --git a/docs/zh-cn/api_overview.md b/docs/zh-cn/api_overview.md
new file mode 100644
index 0000000000..a07cfb7427
--- /dev/null
+++ b/docs/zh-cn/api_overview.md
@@ -0,0 +1,20 @@
+# QMK API
+
+<!---
+ original document: 0.15.12:docs/api_overview.md
+ git diff 0.15.12 HEAD -- docs/api_overview.md | cat
+-->
+
+QMK API提供了一套可用于Web及GUI工具可用的异步API,用于实现将任何[QMK](https://qmk.fm/)支持的键盘的键映射方案进行编译。已有的键映射模板支持所有的QMK键码并且不需要额外的C代码需求。键盘的维护团队可以提供新的模板来启用更多功能的支持。
+
+## App开发者
+
+若您是一位意愿将这套API引入您的程序中的移动端App开发者,请参阅[API使用指引](zh-cn/api_docs.md)。
+
+## 键盘维护团队
+
+若您希望强化您维护的键盘方案在QMK编译API中的支持,请参阅[键盘支持](zh-cn/reference_configurator_support.md)。
+
+## 后端开发者
+
+若您对这套API系统本身感兴趣,请参阅[开发环境](zh-cn/api_development_environment.md)搭建环境并继续深入探索[架构总览](zh-cn/api_development_overview.md)。
diff --git a/docs/zh-cn/cli.md b/docs/zh-cn/cli.md
new file mode 100644
index 0000000000..22c2db92c8
--- /dev/null
+++ b/docs/zh-cn/cli.md
@@ -0,0 +1,43 @@
+# QMK CLI :id=qmk-cli
+
+<!---
+ original document: 0.15.12:docs/cli.md
+ git diff 0.15.12 HEAD -- docs/cli.md | cat
+-->
+
+## 总览 :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` 安装包的开发者,若您愿意为您的操作系统制作安装包,请遵循如下指引:
+
+* 当该系统下的最佳实践与本指引冲突时,请遵循系统的最佳实践方案
+ * 但请在注释中列明此处违反这份指引的原因
+* 在 virtualenv 下安装
+* 指引用户去设置 `QMK_HOME` 环境变量,使得固件源文件拉取路径不再是默认的 `~/qmk_firmware`
diff --git a/docs/zh-cn/cli_commands.md b/docs/zh-cn/cli_commands.md
new file mode 100644
index 0000000000..08d1cc7e79
--- /dev/null
+++ b/docs/zh-cn/cli_commands.md
@@ -0,0 +1,503 @@
+# QMK CLI 命令
+
+<!---
+ original document: 0.15.12:docs/cli_commands.md
+ git diff 0.15.12 HEAD -- docs/cli_commands.md | cat
+-->
+
+# 用户命令
+
+## `qmk compile`
+
+该命令用于在指定目录下编译固件,可用于构建<https://config.qmk.fm>导出的JSON数据,代码库中的键映射,或是当前目录下的键盘。
+
+该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。
+
+**用于配置器导出的数据时**:
+
+```
+qmk compile [-c] <configuratorExport.json>
+```
+
+**用于键映射时**:
+
+```
+qmk compile [-c] [-e <var>=<value>] [-j <num_jobs>] -kb <keyboard_name> -km <keymap_name>
+```
+
+**在键盘目录下时**:
+
+须在存在默认键映射的键盘目录下执行,或是在键盘的键映射子目录下,否则须指定参数 `--keymap <keymap_name>`
+```
+qmk compile
+```
+
+**构建所有支持该键映射的键盘时**:
+
+```
+qmk compile -kb all -km <keymap_name>
+```
+
+**示例**:
+```
+$ 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 <keyboard_name>
+```
+
+**示例**:
+```
+$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi
+$ qmk compile -kb dz60
+Ψ Compiling keymap with make dz60:mechmerlin-ansi
+...
+```
+
+**并行编译**:
+
+在编译时添加 `-j`/`--parallel` 开关可能有助于加快编译速度。
+```
+qmk compile -j <num_jobs> -kb <keyboard_name>
+```
+`num_jobs` 用于指定并行的job上限,将其设置为0可以实现无限制的并行编译。
+```
+qmk compile -j 0 -kb <keyboard_name>
+```
+
+## `qmk flash` :id=qmk-flash
+
+该命令与 `qmk compile` 类似,但额外地可以指定bootloader。bootloader参数是可选的,默认会指定为 `:flash`。可通过 `-bl <bootloader>` 来指定bootloader。请查阅[刷写固件](zh-cn/flashing.md)指引以深入了解可用的bootloader信息。
+
+该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。
+
+**用于配置器导出的数据时**:
+
+```
+qmk flash [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>] <configuratorExport.json>
+```
+
+**用于键映射时**:
+
+```
+qmk flash -kb <keyboard_name> -km <keymap_name> [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>]
+```
+
+**列出所有bootloader**
+
+```
+qmk flash -b
+```
+
+## `qmk config`
+
+该命令用于配置QMK功能,完整的 `qmk config` 文档参见[CLI配置](zh-cn/cli_configuration.md)。
+
+**使用方法**:
+
+```
+qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
+```
+
+## `qmk cd`
+
+该命令会启动一个新的 shell 会话并定位到 `qmk_firmware` 所在目录。
+
+须留意如果你已经位于 `QMK_HOME` 下的某个位置(比如 `keyboards/` 目录中),该指令不会生效。
+
+若要退回到原来的 shell 会话,只需要执行 `exit`。
+
+**使用方法**:
+
+```
+qmk cd
+```
+
+## `qmk console`
+
+该命令用于连接键盘终端并展示调试信息。仅当键盘固件通过 `CONSOLE_ENABLE=yes` 编译时有效。
+
+**用法**:
+
+```
+qmk console [-d <pid>:<vid>[:<index>]] [-l] [-n] [-t] [-w <seconds>]
+```
+
+**示例**:
+
+连接到所有可用的键盘并输出终端信息:
+
+```
+qmk console
+```
+
+列出所有设备:
+
+```
+qmk console -l
+```
+
+仅输出 clueboard/66/rev3 键盘的信息:
+
+```
+qmk console -d C1ED:2370
+```
+
+仅输出第二把 clueboard/66/rev3 键盘的信息:
+
+```
+qmk console -d C1ED:2370:2
+```
+
+输出时间戳及VID:PID以替代键盘名:
+
+```
+qmk console -n -t
+```
+
+屏蔽bootloader的消息:
+
+```
+qmk console --no-bootloaders
+```
+
+## `qmk doctor`
+
+该命令用以检查你的开发环境并对发现的潜在的构建及刷写问题进行提醒,如果您乐意,它也可以修复其中大部分问题。
+
+**用法**:
+
+```
+qmk doctor [-y] [-n]
+```
+
+**示例**:
+
+检查开发环境中的问题并提示是否修复:
+
+ qmk doctor
+
+检查开发环境中的问题并自动进行修复:
+
+ qmk doctor -y
+
+检查开发环境中的问题,仅生成报告:
+
+ qmk doctor -n
+
+## `qmk format-json`
+
+将JSON文件格式化为(尽量)便于阅读的形式。会自动分辨JSON结构类型(info.json还是keymap.json),必要时也可以通过 `--format` 指定。
+
+**用法**:
+
+```
+qmk format-json [-f FORMAT] <json_file>
+```
+
+## `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配置器导出的数据中生成 keymap.c 文件
+Creates a keymap.c from a QMK Configurator export.
+
+**用法**:
+
+```
+qmk json2c [-o OUTPUT] filename
+```
+
+## `qmk c2json`
+
+从 keymap.c 文件中生成 keymap.json
+**注意:** 解析C代码文件并不容易,该命令有可能无法对你的键映射文件生效,不使用C预处理代码有时可以解决问题。
+
+**用法**:
+
+```
+qmk c2json -km KEYMAP -kb KEYBOARD [-q] [--no-cpp] [-o OUTPUT] filename
+```
+
+## `qmk lint`
+
+检查键盘及键映射数据并提示出常见错误与问题,以及不符合模板规范的地方。
+
+**用法**:
+
+```
+qmk lint [-km KEYMAP] [-kb KEYBOARD] [--strict]
+```
+
+该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。
+
+**示例**:
+
+基本的lint检查:
+
+ qmk lint -kb rominronin/katana60/rev2
+
+## `qmk list-keyboards`
+
+该命令可以列出 `qmk_firmware` 中所有的键盘
+
+**用法**:
+
+```
+qmk list-keyboards
+```
+
+## `qmk list-keymaps`
+
+该命令可以列出指定键盘(及指定版本)下的所有键映射。
+
+该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。
+
+**用法**:
+
+```
+qmk list-keymaps -kb planck/ez
+```
+
+## `qmk new-keyboard`
+
+该命令可基于现有模板创建出新的键盘定义。
+
+对于未给出的参数,会提示你输入,若未传入 `-u` 参数且 .gitconfig 中设置了 `user.name`,则会提示你使用该值作为默认用户名。
+
+**用法**:
+
+```
+qmk new-keyboard [-kb KEYBOARD] [-t {avr,ps2avrgb}] -u USERNAME
+```
+
+## `qmk new-keymap`
+
+该命令可基于键盘已有的默认键映射创建新的键映射。
+
+该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。
+
+**用法**:
+
+```
+qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
+```
+
+## `qmk clean`
+
+该命令会清理 `.build` 目录,若传入 `--all` 开关,在 `qmk_firmware` 下的所有.hex及.bin文件也会一并删除。
+
+**用法**:
+
+```
+qmk clean [-a]
+```
+
+---
+
+# 面向开发者的命令
+
+## `qmk format-text`
+
+该命令会重新格式化并统一文件的换行符。
+
+代码库下所有的文件须使用Unix换行符(LF)。
+若你在**Windows**下进行开发,必须确保文件中的换行符是正确的,才能让你的PR被允许合入。
+
+```
+qmk format-text
+```
+
+## `qmk format-c`
+
+该命令会使用clang-format来格式化C代码。
+
+不带参数地执行该命令以用来格式化核心代码相关的改动,默认会通过 `git diff` 来检查 `origin/master`, 可以通过 `-b <分支名>` 来改变检查的分支。
+
+带着 `-a` 开关执行命令会格式化所有的核心代码,也可以在命令行中传入文件名来指定格式化某个文件。
+
+**用以处理指定文件时**:
+
+```
+qmk format-c [file1] [file2] [...] [fileN]
+```
+
+**用以处理所有的核心代码时**:
+
+```
+qmk format-c -a
+```
+
+**用以处理 origin/master 下的所有改动时**:
+
+```
+qmk format-c
+```
+
+**用以处理指定分支下的所有改动时**:
+
+```
+qmk format-c -b branch_name
+```
+
+## `qmk generate-compilation-database`
+
+**用法**:
+
+```
+qmk generate-compilation-database [-kb KEYBOARD] [-km KEYMAP]
+```
+
+创建新 `compile_commands.json` 文件。
+
+你的IDE/编辑器是否使用了“编程语言本地服务器”(language server)且 _总是_ 无法找到全部的包含文件(include files)?是不是很讨厌红色的波浪线?想不想让你的编辑器看得懂 `#include QMK_KEYBOARD_H`?你需要的是一个[编译数据库](https://clang.llvm.org/docs/JSONCompilationDatabase.html)!而 QMK 可以帮助你构建出一个。
+
+该命令需要知道你在构建的是哪个键盘及键映射,它使用与 `qmk compile` 命令一样的选项:参数、当前目录以及配置文件。
+
+**示例:**
+
+```
+$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
+$ qmk generate-compilation-database
+Ψ Making clean
+Ψ Gathering build instructions from make -n gh60/satan:colemak
+Ψ Found 50 compile commands
+Ψ Writing build database to /Users/you/src/qmk_firmware/compile_commands.json
+```
+
+现在可以打开你的开发环境并享受没有波浪线的日子了。
+
+## `qmk docs`
+
+该命令会在本地启动一个HTTP服务,从而你可以浏览及改进文档,默认端口号为8936,使用 `-b`/`--browser` 开关可以让该命令自动通过默认浏览器打开链接地址。
+
+**用法**:
+
+```
+qmk docs [-b] [-p PORT]
+```
+
+## `qmk generate-docs`
+
+该命令可以在本地生成QMK文档,用以文档的常规浏览使用,或进行文档改进工作。可以使用类似[serve](https://www.npmjs.com/package/serve)这样的工具来浏览生成的文档文件。
+
+**用法**:
+
+```
+qmk generate-docs
+```
+
+## `qmk generate-rgb-breathe-table`
+
+该命令可以生成用于[RGB灯光](zh-cn/feature_rgblight.md)的呼吸效果的查询表(LUT)头文件。将该文件命名为 `rgblight_breathe_table.h` 并放入键盘或键映射目录下,可以覆盖替换 `quantum/rgblight/` 下的默认LUT。
+
+**用法**:
+
+```
+qmk generate-rgb-breathe-table [-q] [-o OUTPUT] [-m MAX] [-c CENTER]
+```
+
+## `qmk kle2json`
+
+该命令可以将KLE原始数据转换成QMK配置器的JSON数据,可接受的输入可以是文件绝对路径,或当前目录下的文件名。若 `info.json` 文件存在,默认不会进行覆盖,通过指定 `-f` 或 `--force` 开关可以允许覆盖。
+
+**用法**:
+
+```
+qmk kle2json [-f] <filename>
+```
+
+**示例**:
+
+```
+$ 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 format-python`
+
+该命令可以对 `qmk_firmware` 下的python代码进行格式化。
+
+**用法**:
+
+```
+qmk format-python
+```
+
+## `qmk pytest`
+
+该命令会执行python测试框架,在你更改了python代码后,应确保该命令可以成功执行。
+
+**用法**:
+
+```
+qmk pytest
+```
+
+**示例**:
+
+执行全部的测试套件:
+
+ qmk pytest
+
+执行指定的测试用例组:
+
+ qmk pytest -t qmk.tests.test_cli_commands
+
+执行单个测试用例:
+
+ qmk pytest -t qmk.tests.test_cli_commands.test_c2json
+ qmk pytest -t qmk.tests.test_qmk_path
diff --git a/docs/zh-cn/cli_configuration.md b/docs/zh-cn/cli_configuration.md
new file mode 100644
index 0000000000..d3bca4a338
--- /dev/null
+++ b/docs/zh-cn/cli_configuration.md
@@ -0,0 +1,126 @@
+# QMK CLI 配置
+
+<!---
+ original document: 0.15.12:docs/cli_configuration.md
+ git diff 0.15.12 HEAD -- docs/cli_configuration.md | cat
+-->
+
+本文详述了 `qmk config` 功能及作用。
+
+# 介绍
+
+QMK CLI的配置系统是一套键/值(key/value)数据系统,每个键由一个子指令和一个参数名组成,通过点号(英文句号)分隔。这使得配置项可以简单直接地映射到命令行参数上。
+
+## 简单示例
+
+作为一个示例,对于指令 `qmk compile --keyboard clueboard/66/rev4 --keymap default`
+
+其存在两个命令行参数,可以通过如下方式从配置中读取:
+
+* `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` 命令可以管理配置数据。当不带额外参数执行时,会输出所有已有配置。存在参数时这些参数将被视为配置项参数,其格式须满足如下形式且无空格分隔:
+
+ <subcommand|general|default>[.<key>][=<value>]
+
+## 设置配置值
+
+在配置项的键后加 = 号进行值的设置,配置项的键必须是 `<section>.<key>` 的完整形式。
+
+举例:
+
+```
+$ qmk config default.keymap=default
+default.keymap: None -> default
+Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
+```
+
+## 读取配置值
+
+可以读取整个配置文件、单独配置键或是一整个配置系列,也可以同时指定读取多个配置项。
+
+### 全量配置读取示例
+
+ 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'
+```
+
+## 批量操作
+
+一个指令中可以合并执行多个读写操作,将依序进行执行输出:
+
+```
+$ 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/docs/zh-cn/cli_tab_complete.md b/docs/zh-cn/cli_tab_complete.md
new file mode 100644
index 0000000000..7a16e9766c
--- /dev/null
+++ b/docs/zh-cn/cli_tab_complete.md
@@ -0,0 +1,32 @@
+# QMK Tab补全
+
+<!---
+ original document: 0.15.12:docs/cli_tab_complete.md
+ git diff 0.15.12 HEAD -- docs/cli_tab_complete.md | cat
+-->
+
+在使用Bash 4.2及更高版本、Zsh或FiSH时,可以启用QMK CLI的Tab补全功能,可以实现对 `qmk` 参数中的开关、键盘、文件等参数的自动补全。
+
+## 设置
+
+有以下几种启用Tab补全的方法。
+
+### 仅当前用户生效
+
+将以下内容添加到文件 `.profile` 或 `.bashrc` 的末尾:
+
+ source ~/qmk_firmware/util/qmk_tab_complete.sh
+
+若你的 `qmk_firmware` 存放在其它路径,以上路径也需要调整。
+
+### 系统级的符号关联
+
+若想让所有本地用户都可以实现Tab补全,可以按如下方法添加符号连接到 `qmk_tab_complete.sh` 脚本:
+
+ `ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh`
+
+### 系统级的脚本拷贝
+
+有时符号连接的方案无效,可以改用拷贝文件到指定位置的方案。但须留意该Tab补全脚本可能会不定时更新,你需要定期重新拷贝一次该脚本。
+
+ cp util/qmk_tab_complete.sh /etc/profile.d
diff --git a/docs/zh-cn/configurator_architecture.md b/docs/zh-cn/configurator_architecture.md
new file mode 100644
index 0000000000..386ebd6899
--- /dev/null
+++ b/docs/zh-cn/configurator_architecture.md
@@ -0,0 +1,66 @@
+# QMK配置器框架
+
+<!---
+ original document: 0.15.12:docs/configurator_architecture.md
+ git diff 0.15.12 HEAD -- docs/configurator_architecture.md | cat
+-->
+
+本章节提供了QMK配置器前端技术框架信息,若你对QMK配置器前端工程本身感兴趣,可以从[QMK配置器](https://github.com/qmk/qmk_configurator)代码库开始。
+
+# 总览
+
+![QMK配置器技术框架图](./../configurator_diagram.svg)
+
+# 详述
+
+QMK配置器基于[单页面框架](https://en.wikipedia.org/wiki/Single-page_application)实现,供使用者创建兼容QMK键盘的自定义键映射方案。键映射方案可以导出为JSON格式的数据,也可以编译出可通过[QMK工具箱](https://github.com/qmk/qmk_toolbox)刷写到键盘中的固件文件。
+
+配置器从“键盘元数据仓库(Keyboard Metadata store)”获取键盘元数据,编译请求通过QMK API提交,编译产出放在S3兼容的数据仓库[Digital Ocean空间](https://www.digitalocean.com/products/spaces/)中。
+
+## 配置器前端
+
+地址:<https://config.qmk.fm>
+
+[配置器前端](https://config.qmk.fm)会编译并产出一些静态文件并通过Github Pages托管,每当[QMK配置器 `master`](https://github.com/qmk/qmk_configurator)分支收到推送的提交时都会触发。可以通过[QMK配置器 actions页面](https://github.com/qmk/qmk_configurator/actions/workflows/build.yml)查看这些job的状态。
+
+## 键盘元数据
+
+地址:<https://keyboards.qmk.fm>
+
+每当[qmk_firmware](https://github.com/qmk/qmk_firmware)仓库中的键盘定义变化时,会生成JSON格式的键盘元数据,并上传到指定空间用于配置器生成每种键盘的UI展现。可以在[QMK固件 actions页面](https://github.com/qmk/qmk_firmware/actions/workflows/api.yml)查看相关job的状态。如果你是QMK开发团队成员(Collaborator),可以使用 `workflow_dispatch` 事件触发器来手动执行该job。
+
+## QMK API
+
+地址:<http://api.qmk.fm>
+
+QMK API接受 `keymap.json` 文件输入并进行编译,这和你在 `qmk compile` 和 `qmk flash` 中使用的文件一样。当 `keymap.json` 文件被提交后,浏览器中的页面将定时查看job状态(每2秒一次,有时更久一些)直到job完成。最终产出的JSON描述信息里包含了键映射方案的源文件,及编译出的二进制的可下载链接地址。
+
+为遵循GPL协议,QMK API会确保源文件及编译产出总是同时提供的。
+
+API有3种非异常的回应状态-
+
+1. 编译job排队中
+2. 编译job执行中
+3. 编译job已完成
+
+### 编译job排队中
+
+此状态表明[QMK编译器](#QMK编译器)节点还未选中该job,在配置器页面此时会显示“等待一个可用的烤炉(Waiting for an oven)”。
+
+### 编译job执行中
+
+此状态说明编译job已经在执行中,配置器页面会显示为“烤制中”(Baking)。
+
+### 编译job已完成
+
+此状态说明编译job已经执行完毕,输出的JSON格式的状态信息里有源文件及编译产出的二进制文件的下载链接项。
+
+## Redis/RQ
+
+QMK API通过Redis队列分发job到可用的[QMK编译器](#QMK编译器)节点。接收到的 `keymap.json` 文件先送到RQ队列,而 `qmk_compiler` 节点则从中拉取执行。
+
+## QMK编译器
+
+[QMK编译器](https://github.com/qmk/qmk_compiler)负责执行 `keymap.json` 文件的实际编译工作。它的工作逻辑是先拉取有请求的 `qmk_firmware` 分支代码,执行 `qmk compile keymap.json`,最后上传源文件及二进制产出到Digital Ocean空间中。
+
+当用户需要下载源代码/二进制文件时,API会给出重定向后的已鉴权地址链接。
diff --git a/docs/zh-cn/configurator_default_keymaps.md b/docs/zh-cn/configurator_default_keymaps.md
new file mode 100644
index 0000000000..135029b7e2
--- /dev/null
+++ b/docs/zh-cn/configurator_default_keymaps.md
@@ -0,0 +1,198 @@
+# 向QMK配置器中添加默认键映射 :id=adding-default-keymaps
+
+<!---
+ original document: 0.15.12:docs/configurator_default_keymaps.md
+ git diff 0.15.12 HEAD -- docs/configurator_default_keymaps.md | cat
+-->
+
+本章节描述了如何向QMK配置器中添加一款键盘的默认键映射
+
+
+## 技术信息 :id=technical-information
+
+QMK配置器使用JSON作为键映射的本地文件格式。我们尽力确保其行为与在 `qmk_firmware` 中 执行 `make <keyboard>:default` 时一致。
+
+该目录下的键映射需要定义四个键值对:
+
+* `keyboard` (字符串)
+ * 键盘名称,与执行 `make` 进行编译时使用的一致(如 `make 1upkeyboards/1up60rgb:default`)。
+* `keymap` (字符串)
+ * 应设置为 `default`.
+* `layout` (字符串)
+ * 默认键映射应使用的配列宏定义。
+* `layers` (数组)
+ * 键映射数据。此键下的每行元素对应一个层定义,层定义中包含该层的键码组成信息。
+
+额外地,大部分键映射中还有一个 `commit` 项,该项并不是QMK配置器后端服务API所需,而是用于告知配置器维护者这份JSON键映射数据来源于代码库中的哪个版本的键映射。该值为 `qmk_firmware` 代码库中最后一次修改键盘默认 `keymap.c` 文件提交的commit的SHA标记。该SHA值的获取方式是拉取[`qmk/qmk_firmware` 库的 `master`分支](https://github.com/qmk/qmk_firmware/tree/master/)后,执行 `git log -1 --pretty=oneline -- keyboards/<keyboard>/keymaps/default/keymap.c`(若键盘有什么问题且存在 `keymap.json` 文件,则用之作为替代),执行结果应类似于:
+
+```
+f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from default keymaps (#5625)
+```
+
+本例中,`f14629ed1cd7c7ec9089604d64f29a99981558e8` 即应为 `commit` 的值。
+
+
+## 示例 :id=example
+
+若某人想添加H87a Hineybush键盘的默认键映射方案,应到 `qmk_firmware` 下H87a的默认键映射下执行上述 `git log` 命令:
+
+```
+user ~/qmk_firmware (master)
+$ git log -1 --pretty=oneline master -- keyboards/hineybush/h87a/keymaps/default/keymap.c
+ef8878fba5d3786e3f9c66436da63a560cd36ac9 Hineybush h87a lock indicators (#8237)
+```
+
+在我们获取了commit哈希值后,还需要键映射定义(为加强可读性进行了编辑处理):
+
+```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),
+
+};
+```
+
+默认键映射使用了 `LAYOUT_all` 宏,最后其会成为 `layout` 项的值。编译为QMK配置器的JSON键映射数据后,输出文件应为:
+
+```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"
+ ]
+ ]
+}
+```
+
+`layers` 数组中的空白区域不影响键映射功能,仅为了方便阅读。
+
+
+## 附加说明 :id=caveats
+
+### 层定义只能通过序号进行引用 :id=layer-references
+
+QMK中常见的一种做法是通过一系列 `#define` 或 `enum` 类型声明来对层定义进行命名:
+
+```c
+enum layer_names {
+ _BASE,
+ _MEDIA,
+ _FN
+};
+```
+
+对于C代码来讲可行,但对于配置器来讲,你*必须*使用层序号 - 上例中的`MO(_FN)` 应使用 `MO(2)`。
+
+### 不支持任何形式的定制化代码 :id=custom-code
+
+需要在 keymap.c 文件中添加函数代码的功能,如Tap Dance或是Unicode,都*完全*无法在配置器中构建。即便是在 `qmk_firmware` 代码库中在键盘定义中设置了 `TAP_DANCE_ENABLE = yes`,也只会导致*任何*固件构建在配置器中行不通。这是由API及JSON格式的键映射数据同时造成的限制。
+
+### 对自定义键码的不完全支持 :id=custom-keycodes
+
+仅有一个方案可以支持自定义键码:若自定义键码的逻辑实现是在 qmk_firmware 下的键盘定义中完成的,而非在键映射中,那么这个键码*可以*在配置器中使用且*可以*编译运行。(因此,)相对于在 `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;
+};
+```
+
+... 请将键码的 `enum` 定义块添加到键盘的头文件(`<keyboard.h>`)中,例如(留意 `enum` 在这里命名为 `keyboard_keycodes`):
+
+```c
+enum keyboard_keycodes {
+ MACRO_1 = SAFE_RANGE,
+ MACRO_2,
+ MACRO_3,
+ NEW_SAFE_RANGE // 重要!
+};
+```
+
+... 之后在 `<keyboard>.c` 中的 `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);
+};
+```
+
+注意最后的 `process_record_user()` 调用,若用户需要添加自定义键码到键映射中,须使用 `NEW_SAFE_RANGE` 替代 `SAFE_RANGE`,而其定义来自于上面键盘层定义中。
+
+
+## 更多资料 :id=additional-reading
+
+为了让QMK配置器支持你的键盘,你的键盘定义必须存在于 `qmk_firmware` 代码库的 `master` 分支中。相关操作指引,请参见[在QMK配置器中支持你的键盘](zh-cn/reference_configurator_support.md).
diff --git a/docs/zh-cn/configurator_step_by_step.md b/docs/zh-cn/configurator_step_by_step.md
new file mode 100644
index 0000000000..bbfb71d5a6
--- /dev/null
+++ b/docs/zh-cn/configurator_step_by_step.md
@@ -0,0 +1,63 @@
+# QMK 配置器: 入门
+
+<!---
+ original document: 0.15.12:docs/configurator_step_by_step.md
+ git diff 0.15.12 HEAD -- docs/configurator_step_by_step.md | cat
+-->
+
+本章节描述了如何使用QMK配置器构建出固件文件的过程。
+
+## 第一步:选择键盘
+
+从下拉列表中选择一款用于创建键映射的键盘。
+
+?> 当键盘有多个版本可选择时,请确保选择正确。
+
+因为很重要,这里我再次说一遍:
+
+!> **请选择正确的版本!**
+
+如果你的键盘声称是基于QMK的但未在列表中,可能是开发者还未提交给我们,或者提交还未被合并进来。若在[Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard)中没有找到请求支持该键盘的issue,请到[QMK固件](https://github.com/qmk/qmk_firmware/issues)提交一个issue。也有一些基于QMK的键盘是由制造商自己的GitHub账号在维护着,请也确认一下。 <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
+
+## 第二部:选择键盘配列
+
+选择最适合你要创建的键映射的配列,一些键盘的配列不完整或有问题,后续会逐渐支持。
+
+!> 有时会遇到没有特别适合的配列的情况,请选择 `LAYOUT_all`。
+
+## 第三步:命名你的键映射
+
+如何起名完全取决于你。
+
+?> 如果编译时遇到了问题,可能是因为QMK固件代码库中已经有了同名项,可以尝试改一下名字。
+
+## 第四步:设计你的键映射
+
+以下三种方法可以添加键码:
+
+1. 拖拽
+2. 点击布局上的空白项,再点击所需的键码
+3. 点击布局上的空白项, 再点击你物理键盘上的按键
+
+?> 鼠标在键上悬停时会有一个键码值的提示出现,详细描述信息请参见:
+
+* [基础键码资料](zh-cn/keycodes_basic.md)
+* [进阶键码资料](zh-cn/feature_advanced_keycodes.md)
+
+!> 如果你选择的配列与物理实机有出入,请将不需要的按键留空。如果不清楚应该用哪个键,例如,你只需要一个退格键,但 `LAYOUT_all` 中有两个退格键,须将两个键都放上一样的键码。
+
+## 第五步:保存键映射留待后续修订
+
+当你调整完毕键映射方案,或打算以后继续编辑,点击 `导出Keymap JSON文件(Download this QMK Keymap JSON File)` 按钮,当前键映射方案将保存到你的计算机中,之后可以点击 `导入Keymap JSON文件(Upload a QMK Keymap JSON File)` 按钮导入后继续编辑。
+
+!> **注意:** 导出的.json文件与 kbfirmware.com 和其它工具软件生成的并不兼容,如果你将导出的数据放到那些工具中,或尝试导入那些工具生成的.json文件,是不可行的。
+
+## 第六步:编译固件
+
+点击绿色的 `编译(Compile)` 按钮。
+
+编译完成后,可以点击绿色的 `固件(Download Firmware)` 下载固件文件。
+
+## 下一步:刷写到键盘中
+
+参见[刷写固件](zh-cn/newbs_flashing.md).
diff --git a/docs/zh-cn/configurator_troubleshooting.md b/docs/zh-cn/configurator_troubleshooting.md
new file mode 100644
index 0000000000..a48ad1dd72
--- /dev/null
+++ b/docs/zh-cn/configurator_troubleshooting.md
@@ -0,0 +1,31 @@
+# 配置器问题排查
+
+<!---
+ original document: 0.15.12:docs/configurator_troubleshooting.md
+ git diff 0.15.12 HEAD -- docs/configurator_troubleshooting.md | cat
+-->
+
+## 我的 .json 文件不可用
+
+如果该 .json 文件确实是QMK配置器中导出的,恭喜你遇到bug了,请在[QMK配置器](https://github.com/qmk/qmk_configurator/issues)库中提交一个issue。
+
+如果不是……那么页面顶部加大加粗的提示让你不要使用其它 .json 文件,你是怎么错过的?
+
+## 我的配列中有好多空格键,我应该怎么处理?
+
+如果你是说有三个空格键栏,最好的做法是都放上空格键。这个处理方案也适用于退格键和Shift键。
+
+## 用于...的键码是什么?
+
+参见:
+
+* [基础键码资料](zh-cn/keycodes_basic.md)
+* [进阶键码资料](zh-cn/feature_advanced_keycodes.md)
+
+## 无法编译
+
+请检查键映射中所有的层,确保没有随机(random)键。
+
+## Bug及其它问题
+
+我们很乐意倾听你的需求及bug报告,请到[QMK配置器](https://github.com/qmk/qmk_configurator/issues)代码库中提交吧。
diff --git a/docs/zh-cn/contributing.md b/docs/zh-cn/contributing.md
index 6424d330ce..03d3ea916a 100644
--- a/docs/zh-cn/contributing.md
+++ b/docs/zh-cn/contributing.md
@@ -1,123 +1,78 @@
# 如何做贡献
+<!---
+ original document: 0.15.12:docs/contributing.md
+ git diff 0.15.12 HEAD -- docs/contributing.md | cat
+-->
+
👍🎉 首先感谢各位百忙之中抽空阅读本文档,并为我们无私奉献。给您点赞啦! 🎉👍
-第三方的帮助让Q酱成长了许多呢,Q酱也从你们那学到了不少新东西。Q酱希望每一个想帮助我的人都能很方便的做出有用的贡献。在这里我给摩拳擦掌的你们写了一点引导,让你们的代码在不对我做重大改动的情况下都能成功的被采纳哦。
+第三方的帮助让QMK获得了成长与进步。我们希望提供一套对贡献者和维护者都感到简便实用的PR(pull request)及贡献流程,因此我们整理出了一些准则,以免你的PR在被接纳前需要大改一番。
-* [项目概况](#项目概况)
-* [代码规范](#代码规范)
-* [一般教程](#一般教程)
-* [行为守则对于我来说有何意义?](#行为守则对于我来说有何意义?)
+* [项目概况](#project-overview)
+* [代码规范](#coding-conventions)
+* [一般教程](#general-guidelines)
+* [行为守则对于我来说有何意义?](#what-does-the-code-of-conduct-mean-for-me)
## 这文章巨长无比不想读啊! 我就想问个问题而已!
-您要是想问关于Q酱的问题的话可以在[OLKB Subreddit](https://reddit.com/r/olkb)或者是[Discord](https://discord.gg/Uq7gcHh)随意问。
+您要是有关于QMK的问题,请在[OLKB Subreddit](https://reddit.com/r/olkb)或者是[Discord](https://discord.gg/Uq7gcHh)上进行提问。
请记住:
-* 维护Q酱的小可爱有的时候可能会有点忙,不能及时回答您的问题,耐心等等,他们都是很nice的人呀。
-* 维护Q酱的人都是很无私的善良的人。无论是贡献代码还是回答问题,都是义务的。有时见到他们努力回答各种问题,解决各种BUG,Q酱也是很心疼的。
+* 你的问题也许要过几个小时才会有人回复,请耐心一些。
+* 参与到QMK中的成员都是在无偿地贡献着自己的时间和精力,我们没有受雇于开发QMK或是专职回答你的疑问。
* 您可以看看下面的教程,可以让您的问题浅显易懂,更容易回答:
* https://opensource.com/life/16/10/how-ask-technical-questions
* http://www.catb.org/esr/faqs/smart-questions.html
-# 项目概况
+# 项目概况 :id=project-overview
-Q酱很大一部分是用C语言组成的,不过有一小部分特性是C++的。怎么说呢,都是我的一部分,两个我都爱。Q酱一般是在键盘上的嵌入式处理器那里工作的,尤其与AVR([LUFA](https://www.fourwalledcubicle.com/LUFA.php))和ARM ([ChibiOS](https://www.chibios.org))两小哥哥搭配,干活不累,嘻嘻。如果您精通Arduino的话您会发现很多熟悉的概念,但也有点不爽,因为您以前的经验可能没法用来帮助Q酱。
+QMK很大一部分是C语言编写的,小部分特性是C++的。QMK的设计目标是在键盘上的嵌入式处理器中工作,如AVR([LUFA](https://www.fourwalledcubicle.com/LUFA.php))和ARM ([ChibiOS](https://www.chibios.org))。如果您对Arduino很熟悉的话,会发现优缺点也基本是相似的。但无论你之前是否有Arduino使用经验,都不会影响你参与到QMK贡献中来。
-<!-- 需要修正: 这里放些学习C语言的资源。另外感谢修正的小可爱。谢谢您了。-->
+<!-- FIXME: 这里应当放些C语言的学习资源。 -->
-# Q酱,我在哪能帮助你嘞?
+# 我到哪里寻求帮助?
您要是有问题的话可以 [提出一个issue](https://github.com/qmk/qmk_firmware/issues) 或 [在Discord上交流一下](https://discord.gg/Uq7gcHh).
-# Q酱,我如何帮助你?
+# 我怎样才能做出贡献?
-您以前是否没为开源贡献过代码,而又想知道帮助Q酱是怎么一回事? 稍安勿躁,咱给您总结一下!
+您以前是否没有参与贡献过开源社区,而又想知道如何对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. 把关联着问题的仓库分叉(fork)到你的仓库。这样你在`你的GitHub用户名/qmk_firmware`就有一个仓库备份啦。
-3. 使用 `git clone https://github.com/此处添GitHub用户名/此处添仓库名.git`这个命令把仓库同步到你的电脑中。
-4. 您要是想开发一个新特性的话可以先创建一个issue和Q酱的维护者讨论一下您要做什么。
-5. 使用`git checkout -b 此处写分支名字(别用汉字)`命令来创建一个分支(branch)用于开发。
+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和QMK的维护者讨论一下您要做什么。
+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有点小问题无伤大雅(本来也没有完美的代码嘛), 维护的小可爱们会竭尽全力帮您改进的!
+11. 给你的pull request拟一个标题,包括简短的描述和问题或错误代码。比如, 你可以起一个这样的"Added more log outputting to resolve #4352"(最好用英语,毕竟QMK的维护团队成员都是英语语系,有可能会看不懂中文)。
+12. 在描述(description)里面写你做了哪些更改,你的代码里还存在什么问题, 或者你想对QMK维护着询问的问题。你的pull request有点小问题无伤大雅(没有完美的pull request), QMK维护团队会尽力帮您改进的!
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 完整安装](https://llvm.org/builds/)可以在Windows上安装clang-format, Ubuntu用户要用`sudo apt install clang-format`。
+15. 你的pull request合并成功了,恭喜!
-命令行的朋友们, 加上 `-style=file`选项就会自动在QMK的根目录寻找.clang-format配置文件了。
+# 代码规范 :id=coding-conventions
-VSCode用户, 标准的 C/C++ 插件就支持clang-format, 或者可以用[独立扩展](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat)也行。
+我们的编码风格很容易掌握,如果你有C语言或Python编码经验,跟随我们的编码风格不会有什么困难。
-有些东西(比如LAYOUT宏) 会被clang-format打乱,所以那些文件就别用clang-format了,这里就教您一个小窍门,在`// clang-format off` 和 `//clang-format on`之间装上会被搞乱的代码就好了。
+* [编码规范 - C](zh-cn/coding_conventions_c.md)
+* [编码规范 - Python](zh-cn/coding_conventions_python.md)
-# 一般教程
+# 基本准则 :id=general-guidelines
-你可以给Q酱的不同部分添砖加瓦,但也要用不同的方法严谨检查。不论你修改哪里最好还是看看下边。
+在QMK中存在多种类型的修改需求,因此也会有审查严格性上的差异。请在做出任何修改时留意,你的改动隶属于什么类型。
* 将PR(pull request)分成一个个的逻辑单元。 比如,不要一次将两个新特性PR出去。要添加的特性排好队,一个一个来。
-* 提交之前看一眼,`git diff --check`的空格一定要写对了
+* 提交之前使用 `git diff --check` 做以下检查,不要提交多余的空格
* 确定你的代码能通过编译
- * 布局: 确定`make keyboard:your_new_keymap` 不返回错误
+ * 键映射: 确定`make keyboard:your_new_keymap` 不返回错误
* 键盘: 确定 `make keyboard:all` 不返回错误
* 核心代码: 确定 `make all` 不返回错误
* 提交的信息尽量明确。第一行写点简短介绍(每行不多于70个英文字母), 第二行空着,第三行和后面就要写些必要的细节了。最好用英文写,比如:
@@ -130,13 +85,15 @@ The kerpleplork was intermittently failing with error code 23. The root cause wa
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.
```
+!> **特别留意:** 若你要对其它QMK使用者提交的代码进行功能修改或尝试修复bug,例如非默认的键映射、用户空间和配列部分,须在PR中标记出代码的原始提交者。很多QMK使用者都会对自己提交的代码在不知晓的情况下产生了改动感到困惑和沮丧,无论他的Git及Github经验丰富与否。
+
## 文档
-想帮助Q酱当然是先看文档最简单了。找到这个文档哪里错了然后改正它对于你来说超级简单! 我们也对有写文档能力的人求贤若渴,如果你是对的人[点这个](#Q酱,我在哪能帮助你嘞?)!
+对文档进行修正是最简单的参与贡献的一个办法,找到错误放置的文档或是修复不完备的部分很容易!我们也急需能修订文档的贡献者参与进来,所以如果你具备这样的能力但不清楚如何开始,请[看这里](#我怎样才能做出贡献?)!
-文档呢,都静静的放在`qmk_firmware/docs` 目录里, 也或者您想为网页做贡献的话也是可以的哦。
+文档位于 `qmk_firmware/docs` 目录下,如果你习惯于在web页面中完成工作目标,可以在 https://docs.qmk.fm/ 各文档页面下方点击“Edit this page”在线进行编辑。
-在文档中附代码案例时, 先观察文档其他地方的命名规范。比如, 把enums的名字都改成像`my_layers`或者`my_keycodes`来防止名字不一致的enums被当作特务枪毙:
+在文档中附代码案例时, 先观察文档其他地方的命名规范。比如, 将enum类型的定义命名为 `my_layers` 或 `my_keycodes` 的形式可以保持前后一致性:
```c
enum my_layers {
@@ -150,56 +107,69 @@ enum my_keycodes {
};
```
-## 布局
+### 预览文档 :id=previewing-the-documentation
-大多数QMK新手都从创建一个自己的布局开始。我们尽力保证布局规范宽松 (毕竟布局是个性的体现) 不过建议遵守以下准则,这样可以让别人更好理解你的代码
+在发起pull request前,请通过文档预览来检查你的本地更改。可以在 `qmk_firmware/` 目录下执行以下命令来配置文档开发环境:
-* 用 [模板](documentation_templates.md)写个`readme.md`。
-* 所有的布局PR都会被squash, 如果你想知道你的提交是怎么被squash的那你就自己来吧
-* 不要把新特性和布局一起PR。可以分别PR他们
-* 布局文件夹就不要放`Makefile`了,这个操作都过时啦
-* 更新文件头部的copyrights(看`%YOUR_NAME%`那)
+ qmk docs
+
+或者,如果你有安装Python 3,可以尝试:
+
+ python3 -m http.server 8936 --directory docs
+
+然后在本地浏览器打开 `http://localhost:8936/`.
+
+## 键映射
+
+大多数QMK新手都从创建一个自己的键映射
+开始。我们尽力保证键映射规范宽松 (毕竟键映射体现的是个人喜好) 不过我们仍要求须遵守以下准则,以便他人更好地发现并理解你的键映射代码。
+
+* 使用这份 [模板](zh-cn/documentation_templates.md) 写一份 `readme.md`。
+* 所有的键映射PR都会被压缩处理(squashed,参见[Github文档](https://docs.github.com/cn/github/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges)),如果你对commit被压缩很介意,请自行处理
+* 不要把新特性和键映射放在一个PR中。先提交新特性,再通过PR提交键映射
+* 键映射文件夹中不要提交 `Makefile` 文件(已不再使用)
+* 更新头文件中的copyrights信息(看 `%YOUR_NAME%` 部分)
## 键盘
-QMK的最终归宿是键盘。有些键盘是社区维护的,有一些是制作这些键盘的人维护的。`readme.md`会告诉你是谁维护了这个键盘,如果你对某个键盘有疑问,可以 [创建一个Issue](https://github.com/qmk/qmk_firmware/issues) 来问一问维护者。
+QMK的最终归宿是键盘。有些键盘是社区维护的,有一些是制作这些键盘的人维护的。`readme.md` 会告诉你是谁维护了这个键盘,如果你对某个键盘有疑问,可以 [创建一个Issue](https://github.com/qmk/qmk_firmware/issues) 来问一问维护者。
我们建议你按下面的来操作:
-* 用[模板](documentation_templates.md)写`readme.md`。
-* 提交数量尽量合理,不然我们可就要把你的PR给squash了。
-* 不要把新特性和新键盘一起PR。可以分别PR他们
-* 用父文件夹的名字命名 `.c`/`.h`文件, 比如`/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
+* 基于[模板](zh-cn/documentation_templates.md)编写 `readme.md`。
+* commit数量尽量合理,否则你的PR可能会被我们压缩。
+* 不要把新特性和新键盘定义放在一个PR中。先提交新特性,再通过PR提交新键盘定义
+* 用最近一级的父文件夹的名字命名 `.c`/`.h` 文件, 比如 `/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
* 键盘文件夹就不要放`Makefile`了,这个操作都过时啦
* 更新文件头部的copyrights(看`%YOUR_NAME%`那)
## Quantum/TMK 核心
-在您废寝忘食地开发Q酱新特性或者帮Q酱驱虫之前,一定要确保你的工作是有意义的。看看[了解QMK](understanding_qmk.md)你会对Q酱有更深的了解,这个文档将带你领略QMK的程序流程。现在你应该和维护团对谈谈来了解实现你想法的最佳方法了。一下渠道都可以:
+在你投入大量精力到新功能开发中之前,请先确保使用了最佳的实现方案。通过阅读[了解QMK](zh-cn/understanding_qmk.md)可以获得对QMK的基本认知,这个文档将带你领略QMK的程序流程,然后你可以和维护团队探讨一下实现你想法的最佳方法的思路,以下渠道都可以:
-* [在Discord交流](https://discord.gg/Uq7gcHh)
+* [在Discord中交流](https://discord.gg/Uq7gcHh)
* [建立一个Issue](https://github.com/qmk/qmk_firmware/issues/new)
-新特性和BUG的修复影响所有键盘。开发组也在翻修QMK。所以,在实施重大返修之前一定要讨论一下。如果你在没有事先与维护团队沟通的情况下提交了一个PR,而且你的选择与维护团队的计划方向不符,那你可能要面临大改了。
+新特性和BUG的修复影响所有键盘,开发组也在翻修QMK。所以,在实施重大改动之前一定要讨论一下。如果你在没有事先与维护团队沟通的情况下提交了一个PR,而且你的选择与维护团队的计划方向不符,那你可能要面临大改了。
修复BUG或者开发新特性之前看看这个:
-* **默认不启用** - QMK运行的芯片多数内存有限,所以首要考虑的还应该是布局不要被破坏,于是特性默认是不启用的。你喜欢什么特性的话就打开它,如果你觉得有些特性应该默认开启或者你能帮助缩减代码,那就联系维护组吧。
-* **提交之前在本地编译** - 这个简直就是家喻户晓了,但是也确实需要编译啊! 我们的Travis系统会发现一切问题,但是自己编译一下可要比在线等快多了。
-* **注意版本和芯片平台** - 有那么几个键盘有支持不同配置甚至是不同芯片的版本。试着写一个能AVR和ARM两个平台运行的特性,或者在不支持的平台自动禁用。
+* **默认不启用** - QMK运行的芯片多数内存有限,首要考虑的应是已有的键映射不要被破坏,因此你的功能应当是“可以**启用**”的,而不是“可以禁用”的。如果你觉得该特性应该默认开启或者你能帮助缩减代码,请先和我们沟通一下。
+* **提交之前在本地编译** - 这个简直就是家喻户晓了,但是也确实需要编译啊! 在你发起PR前,请确保任何改动都通过了编译验证。
+* **注意版本和芯片平台兼容性** - 有那么几个键盘有支持不同配置甚至是不同芯片的版本。请确保你开发的特性同时支持AVR和ARM两个平台,或者在不支持的平台自动禁用。
* **解释你的新特性** - 在`docs/`写个文档, 你可以创建新文档或者写到现有文档中。如果你不把它记录下来,其他人就无法从你的努力中获益。
也可以看看以下建议:
-* 提交数量尽量合理,不然我们可就要把你的PR给squash了。
-* 不要把新特性、布局和键盘一起PR。可以分别PR他们。
-* 给你的特性写[单元测试](unit_testing.md)。
-* 你编辑的文件风格要一致,如果风格不明确或者是混搭风的,你就要先看看[代码规范](#代码规范)确认情况。
+* commit数量尽量合理,否则你的PR可能会被我们压缩。
+* 不要把新键盘定义或新键映射与关键改动放在一个PR中。先提交关键改动。
+* 给你的特性编写[单元测试](zh-cn/unit_testing.md)。
+* 你编辑的文件风格要一致,如果风格不明确或者是混搭风的,请先阅读上方的[代码规范](#coding-conventions)。
## 重构
-为了保持QMK脉络清晰,Q酱打算深入规划重构一下自己,然后让合作者进行修改。如果你有重构的思路或建议[创建一个issue](https://github.com/qmk/qmk_firmware/issues), Q酱很乐意讨论一下怎么改进一下。
+为了保持QMK脉络清晰,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) 是说明您有责任尊重和礼貌地对待项目中的每个人,无论他们的身份如何。 如果你是我们行为准则所描述的不当行为的受害者,我们将站在你这边,并按照行为准则对施暴者进行适当谴责。
+我们的[行为守则](https://qmk.fm/coc/) 指出您有责任尊重并礼貌地对待项目中的每个人,无论他们的身份如何。如果你是我们行为守则所描述的不当行为的受害者,我们将站在你这边,尽最大努力对施暴者进行谴责。
diff --git a/docs/zh-cn/custom_quantum_functions.md b/docs/zh-cn/custom_quantum_functions.md
index 1ae996e392..29c5089052 100644
--- a/docs/zh-cn/custom_quantum_functions.md
+++ b/docs/zh-cn/custom_quantum_functions.md
@@ -1,31 +1,35 @@
-# 如何定制你键盘的功能
+# 如何定制化键盘功能
-对于很多人来说客制化键盘可不只是向你的电脑发送你按了那个件这么简单。你肯定想实现比简单按键和宏更复杂的功能。QMK有能让你注入代码的钩子, 覆盖功能, 另外,还可以自定义键盘在不同情况下的行为。
+<!---
+ original document: 0.15.12:docs/custom_quantum_functions.md
+ git diff 0.15.12 HEAD -- docs/custom_quantum_functions.md | cat
+-->
-本页不假定任何特殊的QMK知识,但阅读[理解QMK](understanding_qmk.md)将会在更基础的层面帮你理解发生了什么。
+对于很多人来说对客制化键盘的诉求不只是向电脑输入按下的键。你肯定想实现比简单按键和宏更复杂的功能。QMK支持基于注入点的代码注入,功能重写,另外还可以自定义键盘在不同情况下的行为。
-## A Word on Core vs 键盘 vs 布局
+本页不要求任何额外的QMK知识基础,但阅读[理解QMK](zh-cn/understanding_qmk.md)将会在更基础的层面帮你理解发生了什么。
-我们把qmk组织成一个层次结构:
+## 核心/键盘/键映射的概念 :id=a-word-on-core-vs-keyboards-vs-keymap
+
+QMK基于如下层级组成:
* Core (`_quantum`)
* Keyboard/Revision (`_kb`)
* Keymap (`_user`)
-下面描述的每一个函数都可以在定义上加一个`_kb()`或 `_user()` 后缀。 建议在键盘/修订层使用`_kb()`后缀,在布局层使用`_user()`后缀。
+该文后续部分所提及的函数在定义时皆可添加 `_kb()` 或 `_user()` 后缀,我们建议在键盘及其子版本中使用 `_kb()` 后缀,而在键映射中使用 `_user()` 后缀。
-在键盘/修订层定义函数时,`_kb()`在执行任何代码前先调用`_user()`是必要的,不然布局层函数就不要被调用。
-<!-- 翻译问题:上面那句翻译的不太好-->
+在键盘及其子版本中定义函数时,一个重要的点是在 `_kb()` 函数执行任何逻辑前,应先调用 `_user()` 函数,否则这些键映射中的函数将没有机会被执行。
# 自定义键码
到目前为止,最常见的任务是更改现有键码的行为或创建新的键码。从代码角度来看这些操作都很相似。
## 定义一个新键码
-创建键码第一步,先枚举出它全部,也就是给键码起个名字并分配唯一数值。QMK没有直接限制最大键码值大小,而是提供了一个`SAFE_RANGE`宏。你可以在枚举时用`SAFE_RANGE`来保证你取得了唯一的键码值。
+创建键码的第一步,是先定义其枚举值,也就是给键码起个名字并分配一个唯一值。QMK没有直接限制最大可用的键码值,而是提供了一个 `SAFE_RANGE` 宏。你可以在定义枚举时用 `SAFE_RANGE` 来保证你取得了唯一的键码值。
-这有枚举两个键码的例子。把这块加到`keymap.c`的话你就在布局中能用`FOO`和`BAR`了。
+这有定义两个键码的枚举值的例子。添加以下代码块至 `keymap.c` 后你就可以在布局中使用 `FOO` 和 `BAR` 了。
```c
enum my_keycodes {
@@ -34,15 +38,15 @@ enum my_keycodes {
};
```
-## 为键码的行为编程
+## 编程设计你的键码的行为 :id=programming-the-behavior-of-any-keycode
-当你覆盖一个已存在按键的行为时,或将这个行为赋给新键时,你要用`process_record_kb()`和`process_record_user()`函数。这俩函数在键处理中真实键事件被处理前被QMK调用。如果这俩函数返回`true`,QMK将会用正常的方式处理键码。这样可以很方便的扩展键码的功能而不是替换它。如果函数返回`false` QMK会跳过正常键处理,然后发送键子抬起还是按下事件就由你决定了。
+当你覆盖一个已存在按键的行为时,或是给新按键设计功能时,请使用 `process_record_kb()` 和 `process_record_user()` 函数。QMK会在响应并处理按键事件前调用这些函数,如果这些函数返回值为 `true`,QMK将继续用常规的方式处理键码,这样可以很方便的扩展键码的功能而不需要替换代码实现。如果函数返回`false` QMK会跳过常规的键处理逻辑,需要发送的按键按下或抬起事件则需交由你负责完成。
-当某个键按下或释放时这俩函数会被调用。
+任意按键在按下或抬起时,每次都会调用这些函数。
-### process_record_user()`函数示例实现
+### process_record_user()` 实现示例
-这个例子做了两个事。自定义了一个叫做`FOO`的键码的行为,并补充了在按下回车时播放音符。
+这个例子做了两个事。自定义了一个叫做 `FOO` 的键码的行为,并提供了在按下回车时播放音符的功能。
```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
@@ -51,7 +55,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
// 按下时做些什么
} else {
- // 释放时做些什么
+ // 抬起时做些什么
}
return false; // 跳过此键的所有进一步处理
case KC_ENTER:
@@ -59,21 +63,21 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
PLAY_SONG(tone_qwerty);
}
- return true; // 让QMK触发回车按下/释放事件
+ return true; // 让QMK响应回车按下/抬起事件
default:
- return true; // 正常处理其他键码
+ return true; // 正常响应其他键码
}
}
```
-### `process_record_*` 函数文档
+### `process_record_*` 实现示例
-* 键盘/修订: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)`
-* 布局: `bool process_record_user(uint16_t keycode, keyrecord_t *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` 块来处理这些事件。
+`keycode` 参数为键映射中形如 `MO(1)`,`KC_L` 等定义的键值项。 应使用 `switch...case` 代码块来处理这些事件。
-`record`参数含有实际按键的信息:
+`record` 参数含有按键的真实状态信息:
```c
keyrecord_t record {
@@ -88,108 +92,31 @@ keyrecord_t record {
}
```
-# 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_pre_init_*` - 会在大多数其他功能运行前执行。适用于那些需要尽早执行的硬件初始化工作。
+* `matrix_init_*` - 在固件启动过程中被调用。此时硬件已初始化,但部分功能还不可用。
+* `keyboard_post_init_*` - 在固件启动过程的最后被调用。大多数情况下,你的“客制化”代码都可以放在这里。
-!> 对于大多数人来说`keyboard_post_init_user`是你想要调用的函数。例如, 此时你可以设置RGB灯发光。
+!> 对于大多数人来说 `keyboard_post_init_user` 是你想要关注的函数。例如, 你可以在这里启动RGB背光灯。
## 键盘预初始化代码
-这代码极早运行,甚至都在USB初始化前运行。
+这部分代码执行的非常早,甚至是在USB通信功能启动之前。
-在这之后不久矩阵就被初始化了。
+在这之后不久即会完成矩阵的初始化。
-对于大多数用户来说,这用不到,因为它主要是用于面向硬件的初始化。
+对于大多数用户来说不应在此处进行修改,因为它主要用于硬件初始化。
-但如果你有硬件初始化的话放在这里再好不过了(比如初始化LED引脚一类的).
+但如果你有硬件须初始化的话放在这里再好不过了(比如初始化LED引脚).
-### `keyboard_pre_init_user()`函数示例实现
+### `keyboard_pre_init_user()` 实现示例
-本例中在键盘级别,设定 B0, B1, B2, B3, 和 B4 是LED引脚。
+本例中,在键盘层将 B0, B1, B2, B3, 和 B4 引脚设置为LED引脚。
```c
void keyboard_pre_init_user(void) {
@@ -206,95 +133,110 @@ void keyboard_pre_init_user(void) {
### `keyboard_pre_init_*` 函数文档
-* 键盘/修订: `void keyboard_pre_init_kb(void)`
-* 布局: `void keyboard_pre_init_user(void)`
+* 键盘/各子版本:`void keyboard_pre_init_kb(void)`
+* 键映射:`void keyboard_pre_init_user(void)`
## 矩阵初始化代码
-这将会在矩阵初始化时被调用,在某些硬件设置好后,但在一些功能被初始化前。
+在矩阵初始化后被调用。此时一部分硬件已设置完成,但一些功能尚未完成初始化。
-这在你设置其他地方会用到的东西的时候会很有用,但与硬件无关,也不依赖于它的启动位置。
+此处可以用来设置一些与硬件无关,且对初始化位置没有特殊要求的功能。
-### `matrix_init_*`函数文档
+### `matrix_init_*` 函数文档
-* 键盘/修订: `void matrix_init_kb(void)`
-* 布局: `void matrix_init_user(void)`
+* 键盘/各子版本:`void matrix_init_kb(void)`
+* 键映射:`void matrix_init_user(void)`
+### 低级矩阵函数的重写 :id=low-level-matrix-overrides
-## 键盘后初始化代码
+* GPIO引脚初始化:`void matrix_init_pins(void)`
+ * 此处须完成低级行列引脚的初始化。默认实现中,这里会参考可选的键盘设置项 `ROW2COL`,`COL2ROW` 及 `DIRECT_PINS` 来初始化所有 `MATRIX_ROW_PINS` 及 `MATRIX_COL_PINS` 中定义的GPIO引脚的输入/输出状态。当键盘设计者重写该函数后,QMK本身不会进行任何引脚的初始化,只会听从重写的函数的实现逻辑。
+* `COL2ROW`-从行中读: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
+* `ROW2COL`-从列中读: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)`
+* `DIRECT_PINS`-直读: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
+ * 以上三个函数须参考矩阵类别,从底层矩阵的相关引脚状态中获取输入信息,并且应该只需要实现三者之一。默认情况下,在遍历 `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` 时,会根据是否设置了 `ROW2COL`,`COL2ROW` 或 `DIRECT_PINS` 来配置输入输出方式。当键盘设计者重写该函数后,QMK本身不会进行任何矩阵GPIO引脚状态的变更,只会听从重写的函数的实现逻辑。
-这是键盘初始化过程中的最后一个任务。如果您想更改某些特性,这会很有用,因为此时应该对它们进行初始化。
+## 键盘后初始化代码
+这是键盘初始化过程中的最后一个任务。此时您可以配置并调整某些特性,因为此时这些特性已初始化完毕。
-### `keyboard_post_init_user()`示例实现
+### `keyboard_post_init_user()` 实现示例
-本示例在所有初始化完成后运行,配置RGB灯。
+本示例在所有初始化完成后运行,配置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); // 设置快速呼吸模式不保存
+ 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_kb(void)`
* 布局: `void keyboard_post_init_user(void)`
-# 矩阵扫描代码
+# 矩阵扫描码
-可能的话你要用`process_record_*()`自定义键盘,以这种方式连接到事件中,以确保代码不会对键盘产生负面的性能影响。然而,在极少数情况下,有必要进行矩阵扫描。在这些函数中要特别注意代码的性能,因为它每秒至少被调用10次。
+应尽量使用 `process_record_*()` 实现所需的键盘自定义以及事件监听,以确保这些代码不会对键盘性能产生负面的影响。然而,在极少数情况下需要在矩阵扫描中添加监听,此时需要极端留意这些函数代码的性能表现,因为这些函数每秒可能被执行十数次。
-### `matrix_scan_*`示例实现
+### `matrix_scan_*` 实现示例
-这个例子被故意省略了。在hook这样一个对性能及其敏感的区域之前,您应该足够了解qmk的内部结构,以便在没有示例的情况下编写。如果你需要帮助,请[建立一个issue](https://github.com/qmk/qmk_firmware/issues/new)或[在Discord上与我们交流](https://discord.gg/Uq7gcHh).
+这个例子被故意省略了。在监听处理这样一个对性能及其敏感的部分之前,您应该足够了解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_kb(void)`
* 布局: `void matrix_scan_user(void)`
该函数在每次矩阵扫描时被调用,这基本与MCU处理能力上限相同。在这里写代码要谨慎,因为它会运行很多次。
-你会在自定义矩阵扫描代码时用到这个函数。这也可以用作自定义状态输出(比如LED灯或者屏幕)或者其他即便用户不输入你也想定期运行的功能。
+在需要自定义矩阵扫描代码时可以使用该函数。这也可以用作自定义状态输出(比如LED灯或者屏幕)或者其他即便用户没有输入时你也想定期运行的功能。
+
+# Keyboard housekeeping
+
+* 键盘/各子版本:`void housekeeping_task_kb(void)`
+* 键映射:`void housekeeping_task_user(void)`
+
+该函数在所有QMK处理工作完毕后,下一轮开始执行前被执行。可以放心地假设此时QMK已对最新的矩阵扫描结果完成了所有的处理工作 -- 更新层状态,发送USB事件,更新LED状态,刷新显示屏。
+与 `matrix_scan_*` 类似,这些函数会频繁调用直至MCU处理能力上限。为了确保键盘的响应能力,建议在这些函数中尽量做最少的事情,在你确实需要在这里实现特别的功能时,可能会影响到其它功能的表现。
# 键盘 空闲/唤醒 代码
-如果键盘支持就可以通过停止一大票功能来达到"空闲"。RGB灯和背光就是很好的例子。这可以节约能耗,也可能让你键盘风味更佳。
+在主控板支持情况下,暂停大部分功能可以实现“空闲”状态,例如RGB灯光和背光。既可以节省电量消耗,也可能增强键盘的表现。
-用两个函数控制: `suspend_power_down_*`和`suspend_wakeup_init_*`, 分别在系统板空闲和唤醒时调用。
+这由两个函数控制: `suspend_power_down_*` 和 `suspend_wakeup_init_*`,分别在主控板空闲和唤醒时被调用。
-### suspend_power_down_user()和suspend_wakeup_init_user()示例实现
+### suspend_power_down_user() 和 suspend_wakeup_init_user() 的实现示例
```c
void suspend_power_down_user(void) {
- // code will run multiple times while keyboard is suspended
+ // 当键盘挂起时会被多次调用的代码
}
void suspend_wakeup_init_user(void) {
- // code will run on keyboard wakeup
+ // 键盘唤醒时被调用的代码
}
```
### 键盘 挂起/唤醒 函数文档
-* 键盘/修订: `void suspend_power_down_kb(void)` 和`void suspend_wakeup_init_user(void)`
-* 布局: `void suspend_power_down_kb(void)` 和 `void suspend_wakeup_init_user(void)`
+* 键盘/各子版本:`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_*` 示例实现
+### `layer_state_set_*` 实现示例
-本例使用了Planck键盘示范了如何设置 [RGB背光灯](feature_rgblight.md)使之与层对应
+本例中,通过Planck键盘示范了如何将[RGB背光灯](zh-cn/feature_rgblight.md)设置为与层同步。
```c
layer_state_t layer_state_set_user(layer_state_t state) {
@@ -311,36 +253,41 @@ layer_state_t layer_state_set_user(layer_state_t state) {
case _ADJUST:
rgblight_setrgb (0x7A, 0x00, 0xFF);
break;
- default: // for any other layers, or the default layer
+ 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_*` 函数文档
-* 键盘/修订: `uint32_t layer_state_set_kb(uint32_t state)`
+* 键盘/各子版本:`uint32_t layer_state_set_kb(uint32_t state)`
* 布局: `layer_state_t layer_state_set_user(layer_state_t state)`
-该`状态`是活动层的bitmask, 详见[布局概述](keymap.md#布局的层状态)
+此处的 `state` 为当前活跃层的位掩码, 详见[键映射概述](zh-cn/keymap.md#keymap-layer-status)
-# 掉电保存配置 (EEPROM)
+# 配置的持久存储(EEPROM)
-这会让你的配置长期的保存在键盘中。这些配置保存在你主控的EEPROM里,掉电不会消失。 设置可以用`eeconfig_read_kb`和`eeconfig_read_user`读取,可以用`eeconfig_update_kb`和`eeconfig_update_user`写入。这对于您希望能够切换的功能很有用(比如切换RGB层指示。此外,你可以用`eeconfig_init_kb`和`eeconfig_init_user`来设置EEPROM默认值。
+该功能可以让键盘的配置持久存储下来。这些配置存储在控制器的EEPROM中,即便掉电后依旧可以留存下来。可以通过 `eeconfig_read_kb` 和 `eeconfig_read_user` 来读取,通过 `eeconfig_update_kb` and `eeconfig_update_user` 来进行保存。该功能常用于保存一些开关状态(比如rgb层指示灯)。此外,可以通过 `eeconfig_init_kb` 和 `eeconfig_init_user` 来设置EEPROM的默认配置值。
-最复杂的部分可能是,有很多方法可以通过EEPROM存储和访问数据,并且并没有用哪种方法是“政治正确”的。你每个功能只有一个双字(四字节)空间。
+复杂的地方是,有很多方法可以存储和访问EEPROM数据,并且没有哪种方法是“正确”的。但是,每个功能只有一个双字(四字节)空间可用。
-记住EEPROM是有写入寿命的。尽管写入寿命很高,但是并不是只有设置写道EEPROM中。如果你写入频繁,你的MCU寿命将会变短。
+记住EEPROM是有写入寿命的。尽管写入寿命很高,但是并不是只有这些配置信息会写到EEPROM中。如果你写入过于频繁,你的MCU寿命将会急速减少。
-* 如果您不理解这个例子,那么您可能希望避免使用这个特性,因为它相当复杂。
+* 如果您不理解这个例子,那么您可以不使用这个特性,因为它相当复杂。
-### 示例实现
-
-本例讲解了如何添加设置,并且读写。本里使用了用户布局。这是一个复杂的函数,有很多事情要做。实际上,它使用了很多上述函数来工作!
+### 实现示例
+本例讲解了如何添加并读写设置项。本例使用用户键映射来实现。这是一个复杂的函数,有很多事情要做。实际上,它使用了很多前述的函数来工作!
+(译注:该示例由于英文行文,可能会觉得看得稀里糊涂。实现的功能很简单,即开启了层指示功能(RGB_LYR)时,rgb背光灯会展示当前层的特定颜色用以指示层状态,而触发任何改变rgb背光颜色的键码时,rgb背光灯将回归普通的背光灯角色,不再作为层指示器)
在你的keymap.c文件中,将以下代码添加至顶部:
```c
@@ -354,14 +301,14 @@ typedef union {
user_config_t user_config;
```
-以上代码建立了一个结构体,该结构体可以存储设置并可用于写入EEPROM。如此这般将无需定义变量,因为在结构体中已然定义。要记住`bool` (布尔)值使用1位, `uint8_t`使用8位, `uint16_t`使用16位。你可以混合搭配使用,但是顺序记错可能会招致麻烦,因为那会改变写入写出的值。
+以上代码建立了一个32位的结构体,用于在内存及EEPROM中存储配置项。此时不再需要再单独声明变量,因为都已经在该结构体中定义了。须记住 `bool`(布尔)值占用1位,`uint8_t` 占用8位,`uint16_t` 占用16位。你可以混合搭配使用,但改变这些顺序会因为错误的读写而招致问题。
- `layer_state_set_*`函数中使用了`rgb_layer_change`,使用了`keyboard_post_init_user`和`process_record_user`来配置一切。
+我们在 `layer_state_set_*` 函数中会使用 `rgb_layer_change`。通过 `keyboard_post_init_user` 和 `process_record_user` 来配置所需的一切。
-首先要使用`keyboard_post_init_user,你要加入`eeconfig_read_user()`来填充你刚刚创建的结构体。然后您可以立即使用这个结构来控制您的布局中的功能。就像这样:
+在编写 `keyboard_post_init_user` 时,你需要使用 `eeconfig_read_user()` 来计算并填充你刚刚创建的结构体。然后即可以使用结构体数据来控制键映射中的功能。就像这样:
```c
void keyboard_post_init_user(void) {
- // 调用布局级别的矩阵初始化
+ // 调用键映射级别的矩阵初始化
// 从EEPROM读用户配置
user_config.raw = eeconfig_read_user();
@@ -374,7 +321,7 @@ void keyboard_post_init_user(void) {
}
}
```
-以上函数会在读EEPROM配置后立即使用该设置来设置默认层RGB颜色。"raw"的值是从你上面基于"union"创建的结构体中转换来的。
+以上函数会在读EEPROM配置后立即设置默认层的RGB颜色。"raw"值将被转换为上述创建的实际使用的"union"结构体。
```c
layer_state_t layer_state_set_user(layer_state_t state) {
@@ -398,7 +345,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
return state;
}
```
-这样仅在值使能时会改变RGB背光灯。现在配置这个值, 为`process_record_user`创建一个新键码叫做`RGB_LYR`。我们要确保,如果使用正常的RGB代码,使用上面的示例将其关闭,请将其设置为:
+这样仅在相关值使能时才会改变RGB背光灯。若要配置该值, 为 `process_record_user` 创建一个新键码 `RGB_LYR`。此时我们想实现的是,如果触发了常规的RGB码,以上示例中的逻辑都将不生效,形如:
```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
@@ -407,7 +354,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
// 按下时做点什么
} else {
- // 释放时做点什么
+ // 抬起时做点什么
}
return false; // 跳过此键的进一步处理
case KC_ENTER:
@@ -415,76 +362,116 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
PLAY_SONG(tone_qwerty);
}
- return true; // 让QMK产生回车按下/释放事件
- case RGB_LYR: // 本句让underglow作为层指示,或正常使用。
+ return true; // 让QMK产生回车按下/抬起事件
+ 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) { // 如果层状态被使能
+ 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) { //本句失能层指示,假设你改变了这个…你要把它禁用
+ 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; // 失能,然后
+ user_config.rgb_layer_change = false; // 失能,然后
eeconfig_update_user(user_config.raw); // 向EEPROM写入设置
}
}
return true; break;
default:
- return true; // 按其他键正常
+ return true; // 其他键码正常处理
}
}
```
-最后你要加入`eeconfig_init_user`函数,所以当EEPROM重置时,可以指定默认值, 甚至自定义操作。想强制重置EEPROM,请用`EEP_RST`键码或[Bootmagic](feature_bootmagic.md)函数。比如,如果要在默认情况下设置RGB层指示,并保存默认值
+最后,须添加 `eeconfig_init_user` 函数,从而当EEPROM重置时,可以指定默认值, 甚至自定义操作。若想强制重置EEPROM,请用 `EEP_RST` 键码或[Bootmagic](zh-cn/feature_bootmagic.md) 功能。比如,在你想重置RGB层指示配置,并保存默认值时。
```c
-void eeconfig_init_user(void) { // EEPROM正被重置
+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写入这些值
+ // 通过使用非'noeeprom'版本的函数,可以同时写入这些配置到EEPROM中。
rgblight_enable(); // 默认使能RGB
rgblight_sethsv_cyan(); // 默认设置青色
rgblight_mode(1); // 默认设置长亮
}
```
-然后就完事了。RGB层指示会在你想让它工作时工作。这个设置会一直保存,即便你拔下键盘。如果你使用其他RGB代码,层指示将失能,现在它可以做你所想了。
+一切已就绪,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)`
+* 键盘/各子版本:`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`。
+### 定时执行 :id=deferred-execution
+QMK支持在特定时间间隔后执行回调,以代替手动的计时器管理。
-## `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;
- }
+uint32_t my_callback(uint32_t trigger_time, void *cb_arg) {
+ /* 处理了一些工作 */
+ bool repeat = my_deferred_functionality();
+ return repeat ? 500 : 0;
}
```
-### `get_tapping_term` 函数文档
+第一个参数 `trigger_time` 为预期的执行时间,如果因为其它事情造成了延迟未能在准确的时间点执行,可以利用这个参数“追赶”或者跳过这次间隔,取决于你的目的是什么。
+
+第二个参数 `cb_arg` 为下述的 `defer_exec()` 传入的参数,由此可以获取调用时的状态信息。
+
+返回值为该函数下一次期望被回调的时间间隔毫秒数 -- 若返回 `0` 则会自动被注销掉。上例中,通过执行假想的 `my_deferred_functionality()` 函数来决策回调是否继续下去 -- 若是,则给出一个 `500` 毫秒的延迟计划,否则,返回 `0` 来告知定时处理后台任务该计划已执行完毕。
+
+?> 须留意返回的延时时间是相对原定的触发时间点的,而不是回调执行完的时间点。这样可以防止偶发的执行延迟影响稳定的定时事件计划。
+
+#### 注册定时回调
+
+在定义好回调后,通过如下API进行定时回调注册:
+
+```c
+deferred_token my_token = defer_exec(1500, my_callback, NULL);
+```
+
+第一个参数为执行 `my_callback` 的毫秒时间延迟 -- 上例中为 `1500` 毫秒,即 1.5 秒。
+
+第三个参数为回调执行时传入的 `cb_arg` 参数。须确保该值在回调时依旧有效 -- 局部函数内的变量会在回调执行前就被释放掉因此不能用。如果并不需要这个参数,可以传入 `NULL`。
+
+返回值 `deferred_token` 可被用于在回调执行前取消该定时计划。如果该函数调用失败,会返回 `INVALID_DEFERRED_TOKEN`,一般错误原因是延时值被设置为 `0` 或回调函数参数为 `NULL`,还有一种可能是已有过量的回调在等待被处理 -- 可以按照下述方法修改这个阈值。
+
+#### 延长定时回调时间
+
+由 `defer_exec()` 返回的 `deferred_token` 可以用来修改回调执行所需等待的时延值:
+```c
+// 重新调整 my_token 后续的执行计划为当前时间起800ms后
+extend_deferred_exec(my_token, 800);
+```
+
+#### 取消定时回调
+
+由 `defer_exec()` 返回的 `deferred_token` 可以用来取消掉后续的执行计划:
+```c
+// 取消 my_token 的后续回调
+cancel_deferred_exec(my_token);
+```
+
+一旦 token 被取消了,即视为不再可用。重新使用该 token 是不支持的。
+
+#### 定时回调的限制
+
+可安排的定时回调计划数量是有限的,由 `MAX_DEFERRED_EXECUTORS` 定义的值确定。
+
+如果定时回调注册失败了,可以在对应的键盘或键映射下的 `config.h` 文件中修改该值,比如将默认的 8 改为 16:
+
+```c
+#define MAX_DEFERRED_EXECUTORS 16
+```
-不像这篇的其他功能,这个不需要quantum或者键盘级别的函数,只要用户级函数即可。
diff --git a/docs/zh-cn/driver_installation_zadig.md b/docs/zh-cn/driver_installation_zadig.md
new file mode 100644
index 0000000000..db9bb9a3fd
--- /dev/null
+++ b/docs/zh-cn/driver_installation_zadig.md
@@ -0,0 +1,102 @@
+# 利用Zadig安装Bootloader驱动
+
+<!---
+ original document: 0.15.12:docs/driver_installation_zadig.md
+ git diff 0.15.12 HEAD -- docs/driver_installation_zadig.md | cat
+-->
+
+QMK在主机侧会展现为一台HID键盘设备,因此不需要额外的驱动。但若要在Windows下刷写键盘固件,重置主控板时出现的bootloader设备则通常需要一些驱动程序。
+
+已知的特例有两个:常见于Pro Micro的Caterina bootloader,以及PJRC Teensys上的HalfKay bootloader, 会同时提供一个串行端口设备及一个HID设备,因此不需要额外的驱动。
+
+这里我们推荐使用[Zadig](https://zadig.akeo.ie/)工具软件。若你在MSYS2中配置了开发环境,`qmk_install.sh` 脚本已经替你安装了相关驱动。
+
+## 安装
+
+将键盘重置为bootloader模式,点击 `RESET` 键码(可能在别的层中),或按一下通常在主控板背面上的重置开关,如果你的键盘上没有前两者,尝试在按住Esc键或空格+`B`键时插上键盘(更多信息参见[Bootmagic](zh-cn/feature_bootmagic.md))。有些键盘使用[指令](zh-cn/feature_command.md)功能来代替Bootmagic,这种情况下,可以在键盘插入状态下点击 左Shift+右Shift+`B` 或 左Shift+右Shift+Esc组合键来进入bootloader模式。
+也有一些键盘需要特别的操作才能进入bootloader状态。例如,[Bootmagic](zh-cn/feature_bootmagic.md)键(默认为:Esc键)在其它键上,比如左Control;或是指令组合键(默认为:左Shift+右Shift)为其它组合,如左Control+右Control。当不确定的时候,可以查阅一下主控板的README文件。
+
+若要将USBaspLoader设备置为bootloader模式,请在按住 `BOOT` 按钮时点击 `RESET` 按钮,或是在按住 `BOOT` 按钮时插入USB线缆。
+
+Zadig可以自动检测到bootloader设备,但有时你需要在 **Options(选项) → List All Devices(列出所有设备)** 的下拉列表中选择正确的设备。
+
+!> 如果Zadig中列出的一个或多个设备为 `HidUsb` 驱动的,那么你的键盘应该没有进入bootloader模式,此时箭头会标记成橙色并会询问你确认是否要修改系统驱动,此时**不要**允许该操作。
+
+如果箭头呈现绿色,选择所需的驱动,点击**Install Driver(安装驱动)**。如何选择正确的驱动进行安装请参见[已知驱动列表](#list-of-known-bootloaders)。
+
+![在Zadig中安装了正确的bootloader驱动](https://i.imgur.com/b8VgXzx.png)
+
+最后,重新拔插一次键盘,确认驱动可以正常加载。如果你在使用QMK工具箱进行刷写,记得也重启一下,因为有时它不会检测到驱动的变化。
+
+## 从错误的驱动安装中恢复
+
+如果你发现键盘无法输入了,应当是因为错误地替换了键盘本身的驱动,而不是bootloader的驱动,你的键盘没有进入bootloader模式就进行安装时就会遇到这个问题。在Zadig中很容易看出这个问题 - 正常的键盘在其所有的接口上都应该有 `HidUsb` 驱动:
+
+![在Zadig中的一个正常的键盘](https://i.imgur.com/Hx0E5kC.png)
+
+打开Device Manager(设备管理器),选择**View(查看) → Devices by container(依类型排序设备)**,并定位到你键盘名所在的节点。
+
+![在设备管理器中安装了错误的驱动的主控板](https://i.imgur.com/o7WLvBl.png)
+
+在这些节点上右键,选择**Uninstall device(卸载)**。如果出现了**Delete the driver software for this device(同时卸载该设备驱动文件)**也请勾选上。
+
+![设备卸载确认对话框,选中了“删除驱动文件”](https://i.imgur.com/aEs2RuA.png)
+
+点击 **Action(操作) → Scan for hardware changes(扫描检测硬件改动)**。此时,键盘应该恢复可用状态了。再确认一下Zadig中键盘是否在使用 `HidUsb` 驱动,如果是,键盘即完全恢复可用状态了,如果不是,重复这一步直到Zadig中报告了正确的驱动。
+
+?> 在这一步有时需要重启电脑,以便Windows可以选用新驱动文件。
+
+## 卸载
+
+卸载bootloadeer设备要比安装过程复杂一些。
+
+打开设备管理器,选择**查看 → 依类型排序设备**,并找到bootloader设备,寻找USB VID和PID与Zadig的[该表格](#list-of-known-bootloaders)中一致的项。
+
+在设备属性的详细信息tab中,找到 `Inf name(INF名称)` 值,通常该值类似于 `oemXX.inf`:
+
+![设备属性中的INF名称值](https://i.imgur.com/Bu4mk9m.png)
+
+之后使用管理员权限打开一个命令行窗口(在开始菜单处输出 `cmd` 并点击Ctrl+Shift+回车)。执行 `pnputil /enum-drivers` 并找到 `INF名称` 与 `Published Name(发布名称)` 一致的项:
+
+![对pnputil输出中匹配驱动项进行高亮展示](https://i.imgur.com/3RrSjzW.png)
+
+执行 `pnputil /delete-driver oemXX.inf /uninstall`,之后该驱动会被删除,相关设备也不再使用该驱动,但设备是不会被移除的。
+
+与上一节相似,本流程也可能需要执行多次,因为一个设备可能会有多个可用的驱动。
+
+!> **警告:** 操作过程中*务必非常小心*!以免不小心卸载掉其它关键驱动。如果你对操作不是很确定,多次检查 `/enum-drivers`的输出信息,也可以考虑执行 `/delete-driver` 时不添加 `/uninstall` 开关\。
+
+## 已知驱动列表 :id=list-of-known-bootloaders
+
+该表列出了已知的bootloader设备及其USB VID(厂商ID)和PID(产品ID),以及可用于QMK刷写固件的驱动。留意usbser及HidUsb驱动是随Windows附带的,无法通过Zadig安装 - 如果你的设备驱动不符,请参照上节来卸载这些驱动。
+
+此处列出的设备名应与Zadig中的一致,但不一定与设备管理器及QMK工具箱展示的一致。
+
+|Bootloader |设备名 |VID/PID |驱动 |
+|--------------|------------------------------|--------------|-------|
+|`atmel-dfu` |ATmega16u2 DFU |`03EB:2FEF` |libusb0|
+|`atmel-dfu` |ATmega32U2 DFU |`03EB:2FF0` |libusb0|
+|`atmel-dfu` |ATm16U4 DFU V1.0.2 |`03EB:2FF3` |libusb0|
+|`atmel-dfu` |ATm32U4DFU |`03EB:2FF4` |libusb0|
+|`atmel-dfu` |*none* (AT90USB64) |`03EB:2FF9` |libusb0|
+|`atmel-dfu` |AT90USB128 DFU |`03EB:2FFB` |libusb0|
+|`qmk-dfu` |(键盘名) Bootloader |同`atmel-dfu` |libusb0|
+|`halfkay` |*none* |`16C0:0478` |HidUsb |
+|`caterina` |Pro Micro 3.3V |`1B4F:9203` |usbser |
+|`caterina` |Pro Micro 5V |`1B4F:9205` |usbser |
+|`caterina` |LilyPadUSB |`1B4F:9207` |usbser |
+|`caterina` |Pololu A-Star 32U4 Bootloader |`1FFB:0101` |usbser |
+|`caterina` |Arduino Leonardo |`2341:0036` |usbser |
+|`caterina` |Arduino Micro |`2341:0037` |usbser |
+|`caterina` |Adafruit Feather 32u4 |`239A:000C` |usbser |
+|`caterina` |Adafruit ItsyBitsy 32u4 3V |`239A:000D` |usbser |
+|`caterina` |Adafruit ItsyBitsy 32u4 5V |`239A:000E` |usbser |
+|`caterina` |Arduino Leonardo |`2A03:0036` |usbser |
+|`caterina` |Arduino Micro |`2A03:0037` |usbser |
+|`bootloadhid` |HIDBoot |`16C0:05DF` |HidUsb |
+|`usbasploader`|USBasp |`16C0:05DC` |libusbK|
+|`apm32-dfu` |APM32 DFU ISP Mode |`314B:0106` |WinUSB |
+|`stm32-dfu` |STM32 BOOTLOADER |`0483:DF11` |WinUSB |
+|`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB |
+|`stm32duino` |Maple 003 |`1EAF:0003` |WinUSB |
+|`qmk-hid` |(键盘名) Bootloader |`03EB:2067` |HidUsb |
diff --git a/docs/zh-cn/easy_maker.md b/docs/zh-cn/easy_maker.md
new file mode 100644
index 0000000000..420c77d3af
--- /dev/null
+++ b/docs/zh-cn/easy_maker.md
@@ -0,0 +1,37 @@
+# 极简式制作 - 通过配置器进行一次性的工程构建
+
+<!---
+ original document: 0.15.12:docs/easy_maker.md
+ git diff 0.15.12 HEAD -- docs/easy_maker.md | cat
+-->
+
+你是否需要一种极简的控制器编程方案,类似Proton C或Teensy 2.0,以进行一次性的工程构建?QMK提供了极简制作器,通过QMK配置器可以在几分钟内制作一个固件。
+
+有几种极简制作器,取决于你需要什么样的:
+
+* [引脚直连](https://config.qmk.fm/#/?filter=ez_maker/direct) - 将每个开关独立直连到一个引脚
+* 引脚直连 + 背光 (即将可用) - 类似引脚直连,单独加一个引脚连接到[背光](zh-cn/feature_backlight.md)控制器上
+* 引脚直连 + 小键盘锁 (即将可用) - 类似引脚直连,单独加一个引脚连接到Numlock LED上
+* 引脚直连 + 大写锁 (即将可用) - 类似引脚直连, 单独加一个引脚连接到Capslock LED上
+* 引脚直连 + 编码器 (即将可用) - 类似引脚直连, 再加两个引脚用于连接一个旋钮编码器
+
+## 快速指引
+
+最简单的情况是使用一个引脚直连的主控板,将每个引脚连接到一个开关,另一端再接地即可,从以下键盘列表中可以选择一款支持的MCU:
+
+* <https://config.qmk.fm/#/?filter=ez_maker/direct>
+
+更多信息请参见[引脚直连](#direct-pin)一节。
+
+# 引脚直连 :id=direct-pin
+
+与其名字表意相同,它的原理是一个引脚连接一个开关,每个开关的另一端接地(VSS或GND),不需要额外的部件,通常MCU内部自带上拉电阻,因此可以感知开关动作。
+
+
+这里有一个示意图,展示了如何将一个按钮连接到ProMicro的A3引脚上:
+
+![该示意图中的ProMicro的A3引脚导出一根线,连接到了开关的左边,另一根线从开关右边引出并接地。](https://i.imgur.com/JcDhZll.png)
+
+在开关连接到各自的引脚后,在键盘下拉列表中选择所使用的MCU,将键码指定到对应的引脚上即可构建出固件。以下链接仅展示支持引脚直连的极简式制作:
+
+* <https://config.qmk.fm/#/?filter=ez_maker/direct>
diff --git a/docs/zh-cn/faq.md b/docs/zh-cn/faq.md
deleted file mode 100644
index 3d0b65c6fd..0000000000
--- a/docs/zh-cn/faq.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# 常见问题
-
-* [一般问题](faq_general.md)
-* [构建和编译QMK](faq_build.md)
-* [QMK调试和故障排除](faq_debug.md)
-* [布局问题](faq_keymap.md)
diff --git a/docs/zh-cn/faq_build.md b/docs/zh-cn/faq_build.md
index c4b6e64d8d..84cd3c6a4e 100644
--- a/docs/zh-cn/faq_build.md
+++ b/docs/zh-cn/faq_build.md
@@ -1,122 +1,73 @@
-# 关于构建的常见问题
+# 常被问及的编译问题
-本页所写是QMK构建的常见问题.如果你还没有进行过编译,就看一下[构建环境搭建](getting_started_build_tools.md) 和 [make的说明](getting_started_make_guide.md).
+<!---
+ original document: 0.15.12:docs/faq_build.md
+ git diff 0.15.12 HEAD -- docs/faq_build.md | cat
+-->
-## 如果您不能在Linux上编程
-您需要适当的权限才能操作设备。对于Linux用户, 请参阅下方有关`udev`规则的说明。如果您对`udev`有问题,解决方法是用`sudo`命令。如果您不熟悉此命令,使用`man sudo`查看其手册或[看这个网页](https://linux.die.net/man/8/sudo).
+本页涉及所有编译QMK的问题,如果你还没有试过,请先阅读[编译环境配置](zh-cn/getting_started_build_tools.md)及[Make指引](zh-cn/getting_started_make_guide.md)。
-在你的主控是ATMega32u4时,以下是使用`sudo`命令的样例:
+## 无法在Linux下编程
+操作设备需要足够的权限,对于Linux用户,请参阅下方有关 `udev` 的规则说明。如果你对 `udev` 有困惑,可以先试试 `sudo` 命令,如果你对这个命令不熟悉,可以通过 `man sudo` 或 [这个web页面](https://linux.die.net/man/8/sudo)进行了解。
+
+一个使用 `sudo` 的示例,这里假设你的控制器是ATMega32u4:
$ sudo dfu-programmer atmega32u4 erase --force
$ sudo dfu-programmer atmega32u4 flash your.hex
$ sudo dfu-programmer atmega32u4 reset
-或只用;
+或者只是:
- $ sudo make <keyboard>:<keymap>:dfu
+ $ sudo make <keyboard>:<keymap>:flash
-使用`sudo`运行`make`一般来说**不**推荐,如果可能,尽量使用前一种方法之一。
+但请留意,用 `sudo` 来执行 `make` 通常***不是***一个好主意,请尽量考虑使用上面的办法。
-### Linux `udev` 规则
-在Linux上,您需要适当的权限才能访问MCU。你也可以在刷新固件时使用 `sudo`,或把这些文件放到`/etc/udev/rules.d/`。
+### Linux `udev` 规则 :id=linux-udev-rules
-**/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"
-```
+在linux下,需要足够的权限才能读写bootloader设备,可以使用 `sudo` 来刷写固件(不推荐),也可以将[这个文件](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) 放到 `/etc/udev/rules.d/` 目录下。
+
+放好后,执行:
-**/etc/udev/rules.d/52-tmk-keyboard.rules:**
```
-# tmk键盘产品 https://github.com/tmk/tmk_keyboard
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666"
+sudo udevadm control --reload-rules
+sudo udevadm trigger
```
-**/etc/udev/rules.d/54-input-club-keyboard.rules:**
+
+**注意:**在旧版ModeManager(<1.12)中,过滤功能仅在严格模式(strict mode)下可用,可以调整一下配置:
```
-# Input Club keyboard bootloader
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", MODE:="0666"
+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上检测不到bootloader模式
-确保您的内核对您的设备有相应的支持。 如果你的设备是 USB ACM, 比如Pro Micro (Atmega32u4),就要加上`CONFIG_USB_ACM=y`. 其他设备可能需要`USB_SERIAL` 及其任何子选项。
-
-## DFU Bootloader的未知设备
+### 在Linux下无法检测到bootloader模式下的串口设备
+确认一下你的内核版本是否已配置为支持该设备。如果你的设备使用USB ACM,如Pro Micro(Atmega32u4),确认内核 配置中包含 `CONFIG_USB_ACM=y`,其它类型的设备可能需要 `USB_SERIAL` 及相关子配置的支持。
-如果您在使用Windows来刷新键盘的时候碰到了问题,检查设备管理器。如果在键盘处于 "bootloader模式"时你看到 "未知设备",说明你可能面临设备问题。
+## DFU Bootloader显示为未知设备
-重新运行MSYS2上的安装脚本或许会凑效(比如在MSYS2/WSL运行 `./util/qmk_install.sh`) 或者重新安装QMK工具箱也可能会解决你的问题。
+在Windows下刷写键盘固件时很常见的一个问题。主要原因是安装了错误的驱动,或者压根没有装驱动。
-如果以上方法还是短针攻疽,那您可能需要使用[Zadig Utility](https://zadig.akeo.ie/)。下载此程序, 找到设备问题, 然后选择 `WinUSB`选项, 然后点击"Reinstall driver"。完成后再试试刷新你的键盘。倘若依然徒劳无功,那就尝试所有选项直到好用为止。
+要修复这个问题,可以尝试重新执行QMK安装脚本(位于MSYS2或WSL中的 `qmk_firmware` 目录下的 `./util/qmk_install.sh`)或重新安装QMK工具箱。此外,也可以尝试下载安装[QMK驱动安装包 `qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer)来修复。
-?> 事实上没有一个驱动的最佳选择,有些选项就是和某些系统相辅相成。但libUSB和WinUSB似乎也算是这里的最佳选择了。
-如果bootloader在设备列表中没有显示,你可能要使能 "List all devices"选项在选项菜单中`Options`,然后找到有问题的bootloader设备。(译者注:在win10中可能为 查看-显示隐藏的设备)
+如果问题依旧,可能是需要下载安装Zadig,具体请参考[通过Zadig安装bootloader驱动](zh-cn/driver_installation_zadig.md)。
## USB VID 和 PID
-你可以在编辑`config.h`时使用任何你想用的ID值。实际上,使用任何可能未使用的ID都没有问题,除了有极低的与其他产品发生冲突的可能性。
+通过编辑 `config.h` 你可以自由指定ID,随便选一个看起来不常用的ID一般不会有什么问题,冲突的概率很低。
-大多数QMK主板使用`0xFEED`作为vendor ID。您应该查看其他键盘,以确保选择了唯一的Product ID。
+大部分QMK设备都选用 `0xFEED` 作为VID,选取PID前请先看一下其它键盘的情况再决定。
-也要看看这个。
+同时请阅读这个issue:
https://github.com/tmk/tmk_keyboard/issues/150
-一也可以在下方链接购买一个唯一的VID:PID。不过个人使用似乎用不着这个。
+你可以在以下地址购买唯一的VID:PID,但我觉得个人使用情况下没有必要。
- https://www.obdev.at/products/vusb/license.html
- https://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将解决此问题。
+### 在我刷写完键盘后就没响应了/点了没动静了 -- 设备是arm的(rev6 planck, clueboard 60, hs60v2等)(2019年2月)
+因为ARM平台下EEPROM特殊的工作模式,已保存的配置可能会失效。主要影响的是默认层,有概率在特定情况下会导致键盘不可用,我们还没有搞明白原因。这个问题可以在重置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)
+[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) 以及键盘信息,以了解如何执行此操作的详细信息).
+也可以考虑使用bootmagic,只要它可以用。(参见[Bootmagic文档](zh-cn/feature_bootmagic.md)并结合键盘情况来了解如何操作)
diff --git a/docs/zh-cn/faq_debug.md b/docs/zh-cn/faq_debug.md
index 4dba44c275..63d688ed9e 100644
--- a/docs/zh-cn/faq_debug.md
+++ b/docs/zh-cn/faq_debug.md
@@ -1,136 +1,136 @@
-# 调试的常见问题
+# 调试 FAQ
-本篇详细介绍了人们在键盘故障排除时的各种常见问题。
+<!---
+ original document: 0.15.12:docs/faq_debug.md
+ git diff 0.15.12 HEAD -- docs/faq_debug.md | cat
+-->
-# 调试控制台
+此页面详细介绍了人们对键盘故障排除的各种常见问题。
-## `hid_listen` 无法识别设备
-当设备的调试控制台未就绪时,您将看到如下内容:
+## 调试 :id=debugging
-```
-Waiting for device:.........
-```
-
-插入设备后,*hid_listen*找到该设备,您将收到以下消息:
+如果你在 `rules.mk` 中配置了 `CONSOLE_ENABLE = yes`,你的键盘将会输出调试信息。默认情况下输出很有限,可以启用调试模式来增加调试输出的丰富度。使用你的键映射方案中的 `DEBUG` 键码,或使用[指令](zh-cn/feature_command.md)功能来启动调试模式,或者将下面这段代码放到你的键映射中:
-```
-Waiting for new device:.........................
-Listening:
+```c
+void keyboard_post_init_user(void) {
+ // 通过调整这些值可以改变其表现
+ debug_enable=true;
+ debug_matrix=true;
+ //debug_keyboard=true;
+ //debug_mouse=true;
+}
```
-如果您无法获得这条“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)。
+### 使用QMK工具箱调试
-## Linux或UNIX这样的系统如何请求超级用户权限
-用'sudo'来执行*hid_listen*就有权限了。
-```
-$ sudo hid_listen
-```
+在兼容的平台上,[QMK工具箱](https://github.com/qmk/qmk_toolbox)可以展示你的键盘的调试输出。
-或者把一个文件放到规则文件夹来为TMK设备添加*udev规则*,不同系统的目录可能有所不同。
+### 使用 QMK CLI 进行调试
-文件: /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"
-```
+倾向于在终端进行调试?使用 [QMK CLI 命令行](zh-cn/cli_commands.md#qmk-console)可以展示键盘输出的调试信息。
-***
+### 使用hid_listen调试
-# 其他
-## 安全注意事项
+更喜欢使用终端的方案?PJRC提供的[hid_listen](https://www.pjrc.com/teensy/hid_listen.html)也可以用来展示调试信息,已有Windows、Linux及MacOS下预编译好的可执行文件。
-你应该不想要把你的键盘变成"砖头"吧,就是变成没法重写固件的那种。
-下面讲解一些参数来告诉你什么风险很大(其实也不是很大)。
+## 发送自定义调试信息 :id=debug-api
-- 假如你键盘表面没有设计重置键"RESET", 那你要进入bootloader的话就要按PCB上的RESET了。
- 按PCB上的RESET要拧开键盘底部。
-- 如果 tmk_core / common 里面的文件丢失键盘可能失灵。
-- .hex太大可能不太好; `make dfu` 会删除块,检验大小(咦?好像反了...)。
- 一但出错,刷新键盘失败的话就困在DFU出不去了。
- - 所以, 要知道大小限制。 Planck键盘上.hex文件最大大小是 is 7000h (十进制是28672)
+有时在[自定义代码](zh-cn/custom_quantum_functions.md)中输出调试信息非常有用,要做到这个功能也很简单,在代码文件头部包含 `print.h` 文件:
+```c
+#include "print.h"
```
-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`。
+* `print("string")`: 字符串输出
+* `uprintf("%s string", var)`: 格式化字符串输出
+* `dprint("string")` 仅调试模式下,字符串输出
+* `dprintf("%s string", var)`: 仅调试模式下,格式化字符串输出
-全键无冲还不好用的话试着用`Magic` **N** 命令(默认是`LShift+RShift+N`)。这个命令会在**全键无冲**和**六键无冲**之间临时切换。有些情况**全键无冲**不好用你就需要使用**六键无冲**模式,尤其是在BIOS中。
+## 调试示例
+以下列出了一些实际出现过的调试范例,更多资料参见[调试/定位QMK问题](zh-cn/faq_debug.md)。
-## 指点杆需要复位电路(PS/2 鼠标支持)
-如果没有复位电路,由于硬件初始化不正确,您将得到不一致的结果。查看TPM754复位电路。
+### 当前按下的键的矩阵坐标是什么?
-- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447
-- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf
+在移植或尝试诊断PCB问题时,确认按下的键被正确扫描到是很有用的排查步骤。要启用该场景的日志输出,请在 `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: 0x%04X, col: %u, row: %u, pressed: %b, time: %u, interrupt: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
+#endif
+ return true;
+}
+```
-## 矩阵不可读16以上的列
-当列超过16时[matrix.h]的`read_cols()`中,用`1UL<<16`而不要用`1<<16`。
-
-在C语言中`1` 是一个[int] 类型的[16 bit]值,在AVR中你不能左移大于15次。如果你使用`1<<16`的话会得到意外的零。你要用 [unsigned long]类型,比如`1UL`。
+输出示例
+```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
+```
-https://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279
+### 扫描到一个键码需要多久?
-## 特殊额外键不起作用(系统,音频控制键)
-你要在`rules.mk`定义`EXTRAKEY_ENABLE`在QMK中使用它们。
+调试性能问题时,知晓开关矩阵的扫描频率是很有用的排查步骤。要启用该场景的日志输出,请在 `config.h` 中添加:
+```c
+#define DEBUG_MATRIX_SCAN_RATE
```
-EXTRAKEY_ENABLE = yes # 音频控制和系统控制
-```
-
-## 睡眠唤醒不好用
-
-在Windows查看设备管理器中该键盘设备属性中电源管理选项卡中的`允许此设备唤醒计算机(O)`是否勾选。同时看一眼BIOS设置。
-在主机睡眠时按下任何键都可以唤醒了。
+输出示例
+```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
+```
-## 使用Arduino?
+## `hid_listen` 无法识别到设备
-**注意Arduino的针脚名字和主控芯片的不一样。** 比如, Arduino的`D0`并不是`PD0`。自己用原理图捋一下电路。
+如果设备没有就绪,在命令行下调试会看到如下输出:
-- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf
-- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf
+```
+Waiting for device:.........
+```
-Arduino Leonardo和micro使用**ATMega32U4**,该芯片TMK可用,但Arduino的bootloader会导致问题。
+当设备插入后,*hid_listen*可以发现设备,会有如下输出:
-## USB 3 兼容性
-据传说有些人用USB3接口会有问题,用USB2的试试。
+```
+Waiting for new device:.........................
+Listening:
+```
+若无法出现'Listening:'消息,尝试在[Makefile]中添加 `CONSOLE_ENABLE=yes`
-## Mac 兼容性
-### OS X 10.11 和集线器
-https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034
+在类Linux系统下,访问设备可能需要一定权限,尝试使用 `sudo hid_listen`。
+此外,很多Linux发行版可以通过创建如下内容的文件 `/etc/udev/rules.d/70-hid-listen.rules` 来避免通过root权限执行hid_listen:
-## 对于BIOS (UEFI)/恢复(睡眠和唤醒)/重新启动 有问题
-有人说他们的键盘在BIOS中,或许是恢复(睡眠和唤醒)后不工作.
+```
+SUBSYSTEM=="hidraw", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="def1", TAG+="uaccess", RUN{builtin}+="uaccess"
+```
-截止至目前,其根本原因未知,不排除与某些构建选项有关。试着在Makefile中失能`CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE`这样的选项,也试试其他的。
+使用设备的真实VID和PID替换上面的abcd和def1,留意必须全小写。其中 `RUN{builtin}+="uaccess"` 仅在较老的发行版中需要使用。
-https://github.com/tmk/tmk_keyboard/issues/266
-https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778
+## 命令行无法成功输出消息
+请检查:
+- *hid_listen*确实找到了设备,如前文所述。
+- 通过**Magic**+d命令启用调试模式,参见[Magic Commands](https://github.com/tmk/tmk_keyboard#magic-commands).
+- 配置`debug_enable=true`. 参见[调试](#debugging)
+- 尝试用 `print` 替代 `dprint`, 参见**common/print.h**.
+- 拔出其它可能影响命令行的设备,参见[Issue #97](https://github.com/tmk/tmk_keyboard/issues/97).
diff --git a/docs/zh-cn/faq_general.md b/docs/zh-cn/faq_general.md
index 4949acb8c9..cc8ef3d19a 100644
--- a/docs/zh-cn/faq_general.md
+++ b/docs/zh-cn/faq_general.md
@@ -1,19 +1,58 @@
-#
+# 常见问题(FAQ)
-## QMKʲô?
+<!---
+ original document: 0.15.12:docs/faq_general.md
+ git diff 0.15.12 HEAD -- docs/faq_general.md | cat
+-->
-[QMK](https://github.com/qmk), ӻе(Quantum Mechanical Keyboard)дһȺԴΪƼ̿ĹߡǴ[QMK̼](https://github.com/qmk/qmk_firmware)ʼ[TMK](https://github.com/tmk/tmk_keyboard)ħķֲ档
+## QMK是什么?
-### Ϊʲô(Quantum)?
+[QMK](https://github.com/qmk), 是量子机械键盘(Quantum Mechanical Keyboard)的缩写, 是制作自定义键盘工具的人组成的组织。 一切始于[QMK固件](https://github.com/qmk/qmk_firmware)项目, 可以认为是[TMK](https://github.com/tmk/tmk_keyboard)的改进版本.
-<!-- ޸ ²ۣĵ߾ȻҲ֪Ϊɶ -->
+## 不知道从哪开始搞!
-## QMKTMKʲô?
+这样的话建议从[新手指引](zh-cn/newbs.md)开始。那里有你需要的高质量的入门信息。
-TMK[Jun Wako](https://github.com/tmk)ƺִСQMKʼ[Jack Humbert](https://github.com/jackhumbert)ΪPlanck̴TMKֲ档һʱJackķֲͺTMKȥԶˣ2015꣬JackQMK
+如果还是搞不懂的话,直接跳到[QMK配置器](https://config.qmk.fm)吧,你核心需要的东西都在那里。
-Ӽ۵QMKTMKһЩ¹ܶɵġQMKչ˿õļ룬ʹ߼ܽһḻ `S()`, `LCTL()`, `MO()`ȫ[](keycodes.md).
+## 我的固件如何刷写到硬件上?
-ӹ̵TMKԼάйٷֵ֧ļֻ̣кСһ֧֡άѴڷֲΪ̴ķֲ档Ĭֺ֧ٵļ룬ûͨ˷֡QMKͨйֺֿͼ̣ǻз׼PRͼı֤άͬʱQMKСҲڱҪʱ
+先参考[编译/刷写固件FAQ](zh-cn/faq_build.md),里面有充足的资料,常见的问题也给出了足够多的解决办法。
-ַŵȱ㣬ҴʱTMKQMK֮
+## 我的问题这里找不到相关信息怎么办?
+
+没有关系,请到[GitHub上发issue](https://github.com/qmk/qmk_firmware/issues)看看是否有人遇到了相同的问题(留意一定是相同的问题,而不是相似的)。
+
+如果还是找不到解决办法,请[新建issue](https://github.com/qmk/qmk_firmware/issues/new)!
+
+## 我好像找到了bug?
+
+那么新建一个[issue](https://github.com/qmk/qmk_firmware/issues/new)吧,如果你还知道怎么修,带着修复方案发个Pull Request吧。
+
+## 但是 `git` 和 `GitHub` 我实在是玩不转!
+
+别担心,这里有很好的[入门指引](zh-cn/newbs_git_best_practices.md)可以教你怎么轻松快乐地使用 `git` 和GitHub进行开发。
+
+更多的 `git` 和GitHub知识,参考[这里](zh-cn/newbs_learn_more_resources.md)。
+
+## 我可以添加一个支持的键盘
+
+太棒啦!请发Pull Request吧,在代码审阅后,我们会合并进去!
+
+### 我可以打上 `QMK` 的标吗?
+
+很好啊!我们甚至乐意帮你这么做!
+
+我们有[一整页](https://qmk.fm/powered/)的资料旨在帮你在页面和键盘上打上QMK的标,里面有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 fork。一段时间后,Jack的这个fork与TMK渐行渐远,到2015年时,Jack决定将这份fork重命名为QMK。
+
+技术上讲QMK等同于基于TMK增加了一些新功能,最显著的是在扩充了可用键码后,实现了很多诸如 `S()`, `LCTL()` 及 `MO()` 这样的高级功能,所有这些键码可以参见[键码](zh-cn/keycodes.md)页。
+
+从工程项目及社区维护角度来看,TMK维护了一份官方支持的键盘及很少量的社区贡献,社区中各自维护着各自的fork,且因为默认键映射很少,TMK的使用者基本不会共享键映射。QMK通过统一的集约式仓库(repo)管理来鼓励分享键盘及键映射,任何符合质量基线的pull request都会被采纳,因此绝大部分贡献都来源于社区,QMK小组会在必要时提供支援。
+
+两种模式各有利弊,并且TMK和QMK之间也会有合乎理法的代码交流。
diff --git a/docs/zh-cn/faq_keymap.md b/docs/zh-cn/faq_keymap.md
index ff38f38894..f674129717 100644
--- a/docs/zh-cn/faq_keymap.md
+++ b/docs/zh-cn/faq_keymap.md
@@ -1,151 +1,157 @@
-# 布局常见问题
+# 键映射FAQ
-本页本页包含人们经常遇到的关于布局的问题。如果你觉得没什么问题,请先看[布局概览](keymap.md)。
+<!---
+ original document: 0.15.12:docs/faq_keymap.md
+ git diff 0.15.12 HEAD -- docs/faq_keymap.md | cat
+-->
-## 我能用什么键码?
-看[键码](keycodes.md)你可以找到你能用的键码索引。可以的话这些链接可以连接到更广泛的文档。
+本页包含人们经常遇到的关于键映射的问题,如果你还没阅读过[键映射概览](zh-cn/keymap.md),请先阅读一下。
-键码实际上定义在[common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h).
+## 我能使用的键码有哪些?
+所有可用键码收录在[键码](zh-cn/keycodes.md)页,在有更详尽的文档时,我们会更新这个链接。
-## 默认的键码什么样?
+所有键码实际定义在[quantum/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h).
-世界上有三种标准键盘设计,分别是:ANSI, ISO, and JIS. 主要是北美用ANSI(译者注:中国很多键盘使用这个), 欧洲和非洲主要使用ISO,日本使用JIS。未提及的区域通常使用ANSI或ISO。与这些设计对应的键代码如下所示:
+## 默认键码是什么?
-<!-- 该图片的来源: https://www.keyboard-layout-editor.com/#/gists/bf431647d1001cff5eff20ae55621e9a -->
-![键盘设计图](https://i.imgur.com/5wsh5wM.png)
+广为使用的键盘配列有三种——ANSI,ISO及JIS。北美主要使用ANSI,欧洲及非洲主要使用ISO,日本主要使用JIS,其它区域多为ANSI或ISO。这三种配列的键码可查阅:
-## 我有一些键变成了其他功能或者不工作了
+<!-- Source for this image: https://www.keyboard-layout-editor.com/#/gists/bf431647d1001cff5eff20ae55621e9a -->
+![键盘配列示意图](https://i.imgur.com/5wsh5wM.png)
-QMK有两个功能,Bootmagic和命令行,它允许您在运行中更改键盘的行为。该功能包括但不仅限于, 交换Ctrl/Caps,关闭界面,交换Alt/Gui,交换 Backspace/Backslash,禁用所有键,以及其他的行为改变。
+## 如何对复杂的键码指定自定义的名称?
-快速解决方法是插入键盘时按住`Space`+`Backspace`。该操作将重置已保存设置,让这些键回复初始功能。这招不好用的话参阅下方:
+使用更容易理解的自定义的名字去指代一些键码有时很实用,通常我们使用 `#define` 来实现:
-* [Bootmagic](feature_bootmagic.md)
-* [命令](feature_command.md)
+```c
+#define FN_CAPS LT(_FL, KC_CAPSLOCK)
+#define ALT_TAB LALT(KC_TAB)
+```
+
+这样键映射代码中就可以使用 `FN_CAPS` 和 `ALT_TAB` 了,可读性好得多。
+
+## 一些按键发生了交换,或是不能用了
+
+QMK有两个功能系列,Bootmagic及指令,都可以让键盘随时变得灵活多变,功能包含但不限于交换Ctrl/Caps、锁定Gui键、交换Alt/Gui、交换Backspace/Backslash、禁用所有按键等。
-## 菜单键不好用
+快速恢复的办法是插入键盘时按住空格+`Backspace`键,这样会重置键盘内存储的设置信息,键盘就会恢复常态。如果问题依旧存在,请参考:
-现在大多数键盘 `KC_RGUI`和`KC_RCTL`中间的键子叫做`KC_APP`。这是因为在这个键子发明之前相关标准里就已经有键叫做`MENU(菜单)`了,所以微软叫他`APP(应用)`键。
+* [Bootmagic](zh-cn/feature_bootmagic.md)
+* [指令](zh-cn/feature_command.md)
-## `KC_SYSREQ` 不工作
-使用抓屏的键码(`KC_PSCREEN`或`KC_PSCR`)而不用`KC_SYSREQ`。组合键'Alt + Print Screen'会被当作'System request'。
+## 菜单键(Menu)不可用
-见[issue #168](https://github.com/tmk/tmk_keyboard/issues/168)和
+现代键盘上,位于 `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)以及
* https://en.wikipedia.org/wiki/Magic_SysRq_key
* https://en.wikipedia.org/wiki/System_request
## 电源键不工作
-这有点让人困惑,QMK有两个"Power(电源)"键码: `KC_POWER` 在键盘/小键盘的HID使用页面中,`KC_SYSTEM_POWER` (或者叫`KC_PWR`)在用户页。
+QMK有两个容易让人迷惑的“电源键”键码:HID键盘页的 `KC_POWER`,及用户页的 `KC_SYSTEM_POWER`(或 `KC_PWR`)。
-前者只能被macOS识别,但是后者,即`KC_SLEP`和`KC_WAKE`三大主要操作系统全都支持,所以推荐使用这两个。Windows下这些键立即生效,macOS要长按直到弹出对话框。
+前者只有macOS支持,后者连同 `KC_SLEP` 及 `KC_WAKE` 在所有主流操作系统上都支持,因此使用后者是推荐的做法。在Windows下,按下按键即刻就会生效,而macOS下必须按住直到系统弹出一个对话框。
-## 自动大小写锁定
-可以解决'the'问题(正常应为The)。我经常在输入'The'时不慎输入了'the'或者'THe'。自动大小写锁定可以修正此类问题。详见下方链接。
+## 单发修饰键
+用来解决我自己的’the‘麻烦,我总是会将’The‘错输入为’the‘或’THe‘,单发Shift键缓解了我的这个麻烦。
https://github.com/tmk/tmk_keyboard/issues/67
-## 修改 键/层 卡住
-除非正确配置层切换,否则修改键或层可能会卡住。
-对于修改键和图层操作,必须把`KC_TRANS`放到目标层的相同位置,用于注销修改键或在释放事件时返回到上一层。
+## 修饰键/层 卡住了
+层切换功能只有在正确配置的情况下,才不会出现卡住修饰键和层的问题。
+对于修饰键和层切换操作来讲,必须确保 `KC_TRANS` 在切换到目标layer时正确置位,才能让修饰键正确释放。或者在释放动作中确保返回到了之前的层。
+
* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching
* https://geekhack.org/index.php?topic=57008.msg1492604#msg1492604
* https://github.com/tmk/tmk_keyboard/issues/248
-## 机械自锁开关支持Mechanical Lock Switch Support
+## 机械锁定式开关支持
-本功能用于*机械自锁开关*比如[this Alps one](https://deskthority.net/wiki/Alps_SKCL_Lock)。你可以通过向`config.h`添加以下宏来使能该功能:
+该功能支持形如[Alps这款](https://deskthority.net/wiki/Alps_SKCL_Lock)的*机械锁定式开关*,启用该功能须在 `config.h` 中添加如下定义:
```
#define LOCKING_SUPPORT_ENABLE
#define LOCKING_RESYNC_ENABLE
```
-在使能该功能后,要在键盘中使用`KC_LCAP`, `KC_LNUM` 和 `KC_LSCR`这三个键码。
+启用该功能后,在你的键映射中须改为使用 `KC_LCAP`,`KC_LNUM` 和 `KC_LSCR`。
-远古机械键盘偶尔会有自锁机械开关,现在几乎没有了。***大多数情况下你不需要使用该功能,且要使用`KC_CAPS`, `KC_NLCK`和`KC_SLCK`这三个键码。***
+旧式复古风(vintage style)键盘偶尔能见到锁定式开关,但在现代键盘中见不到了。***因此你基本不会需要这个功能的,直接使用 `KC_CAPS`,`KC_NLCK` 和 `KC_SLCK` 就好***
-## 输入ASCII之外的特殊字符比如Cédille 'Ç'
+## 输入形如法语中软音'Ç'这样的非ASCII字符
-请见[Unicode](feature_unicode.md)功能。
+参见[Unicode](zh-cn/feature_unicode.md)功能.
-## macOS上的`Fn`
+## macOS系统下的 `Fn`
-不像大多数FN键,苹果上那个有自己的键码...呃,基本上算吧。 他取缔了基本6键无冲HID报告的第六个键码 -- 所以苹果键盘其实是5键无冲的。
+和其它键盘不同,Apple键盘上的Fn有自己的键码...在某种程度上。其占用了基础6KRO HID事件上报中的第六个键码 —— 因此Apple键盘实际上只是5KRO(5键无冲)的。
-技术上说QMK可以发送这个键。但是,这样做需要修改报告格式以添加FN键的状态。这还不是最糟糕的,你的键盘的VID和PID和真的苹果键盘不一样的话还不会被识别。
-QMK官方支持这个会被律师函的,所以就当我没说过。
+技术上讲QMK确实能发送这种键码,但这么做需要修改上报事件中Fn键状态的格式。更麻烦的是,只有你的键盘的VID及PID与Apple键盘一致时才会生效。QMK对此提供官方支持可能会有法律风险,换句话说,我们不太可能去这么做的。
-详见[issue#2179](https://github.com/qmk/qmk_firmware/issues/2179)。
+具体信息请参见[这个issue](https://github.com/qmk/qmk_firmware/issues/2179)。
+## Mac OSX下支持的键有哪些?
+你可以通过查阅以下代码确认OSX下支持的键码。
-## 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内部键码).
+`usb_2_adb_keymap` 数组实现了从 Keyboard/Keypad 页到 ADB 扫描码(OSX内部使用的键码)的转换。
https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c
-`IOHIDConsumer::dispatchConsumerEvent`会处理用户页面用法。
-<!--翻译问题:上面那两句翻译的不好-> handles Consumer page usages. -->
+以及 `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键
+## Mac OSX下的JIS键
+日语体系的JIS键盘有些特殊键码:`無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` 在OSX下无法被识别,可以尝试通过以下配置借助 **Seil** 来启用这些键。
-https://pqrs.org/osx/karabiner/seil.html
+* 在PC键盘中启用NFER键
+* 在PC键盘中启用XFER键
+* 在PC键盘中启用KATAKANA键
+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
-此问题详见下方链接。
+## RN-42蓝牙模块与Karabiner的兼容性问题
+Karabiner - Mac OSX系统下的键映射工具 - 默认会忽略RN-42模块的输入事件。须在Karabiner开启相关选项来支持你的键盘。
+https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559230
+这个问题的其它详细信息参见
https://github.com/tmk/tmk_keyboard/issues/213
https://github.com/tekezo/Karabiner/issues/403
-## Esc 和 <code>&#96;</code> 双功能键
-
-请见[Grave Escape](feature_grave_esc.md)功能。
+## Esc和<code>&#96;</code>位于同一个键位
-## Mac OSX的弹出键
-`KC_EJCT` 键码在OSX可以使用 https://github.com/tmk/tmk_keyboard/issues/250
-似乎Windows10会忽略该键码,Linux/Xorg可以识别该键码但默认不映射。
+参见[Grave Escape](zh-cn/feature_grave_esc.md)功能.
-目前尚不清楚如何在真正的苹果键盘按出弹出键。HHKB使用`F20`用于弹出键(`Fn+f`),该功能在MAC模式有效但不保证与苹果弹出键码相符。
+## Mac OSX下的弹出功能
+`KC_EJCT` 在OSX下可用。 https://github.com/tmk/tmk_keyboard/issues/250
+Windows 10应该是忽略了这个键码,Linux/Xorg能识别到,但默认没有映射处理。
+目前尚不清楚Apple键盘上弹出键到底是啥,HHKB在Mac模式下使用 `F20` 来作为弹出键(`Fn+f`),但应该和Apple的弹出键码不是一回事儿。
-## `action_util.c`中的 `weak_mods`和`real_mods`是什么
-___待改善___
+## 在 `action_util.c` 中的 `weak_mods` 和 `real_mods` 是什么东西?
+___待完善的内容___
-real_mods 用于保存实际(物理)修改键的实际状态。
-weak_mods 用于保存虚拟或临时修改键,它将不会影响实际修改键。
+real_mods保存的是现实的/物理上的修饰键状态,而weak_mods保存的是虚拟的或临时的修饰键状态,且不应该影响到真实的修饰键的状态。
-以按下左侧Shift键然后输入ACTION_MODS_KEY(LSHIFT, KC_A)为例,
+例如你按住了物理键盘上的左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): 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时,
+* (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现已全部加入键盘数据包发送豪华套餐。
+在键盘事件发送时,weak_mods会与real_mods求逻辑或。
https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57
diff --git a/docs/zh-cn/faq_misc.md b/docs/zh-cn/faq_misc.md
new file mode 100644
index 0000000000..d01caba3be
--- /dev/null
+++ b/docs/zh-cn/faq_misc.md
@@ -0,0 +1,108 @@
+# 其它 FAQ
+
+<!---
+ original document: 0.15.12:docs/faq_misc.md
+ git diff 0.15.12 HEAD -- docs/faq_misc.md | cat
+-->
+
+## 怎么对键盘进行测试? :id=testing
+
+测试键盘就简单直接,把每个按键按一遍后确认发送的是正确的就行。也可以使用[QMK配置器](https://config.qmk.fm/#/test/)的测试模式检查键盘,即便这键盘没有运行着QMK。
+
+## 安全措施
+
+你应该不想见到键盘变砖,变得不能再刷写固件。这里给出了一些非常危险(或相反不太危险)的因素。
+
+- 如果你的键盘没有RESET键,在你需要进入DFU模式时,不得不需要用螺丝刀打开后盖去按PCB上的RESET键。
+- 把 tmk_core/common 下的文件搞乱的话,容易导致键盘无法使用
+- .hex文件太大的话也会引起问题。`make dfu` 会先擦除存储块,再检查固件大小(哎呀,顺序错了),此时发现错误进而导致刷写失败,键盘停留在DFU模式下。
+ - 因此,请留意.hex文件尺寸有大小限制,例如在Planck上是十六进制7000(十进制的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被覆写(除非你往DFU工具上塞自己的东西),这个风险不大。
+- EEPROM的写循环一般是 100000(100k)次,不应不停地持续重复地刷写固件,不然很快就烧毁了。
+
+## NKRO 不好使
+首先请确保在编译固件时有在**Makefile**中启用 `NKRO_ENABLE`
+
+如果依旧不行,尝试一下 `Magic` **N** 指令(默认是左Shift+右Shift+N),这个指令可以让键盘在**NKRO**和**6KRO**模式间临时切换。有的场景下**NKRO**无法工作必须切换到**6KRO**模式,比如在BIOS中操作时。
+
+如果你的固件编译时指定了 `BOOTMAGIC_ENABLE` ,则需要使用 `BootMagic`**N** 指令(默认是空格+N)。这个配置保存在EEPROM中,断电也会留存。
+
+https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch
+
+
+## 轨迹球需要复位电路 (PS/2鼠标支持)
+缺失复位电路的情况下,由于不正确的硬件初始化,可能会导致设备不稳定,具体请参阅TPM754的电路原理图:
+
+- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447
+- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf
+
+
+## 无法读到大于16的矩阵列
+当列数大于16时,在 [matrix.h] 中的 `read_cols()` 中请用 `1UL<<16` 替代 `1<<16`。
+
+在C语言中,对于AVR上的 `1`,会被视作一种[16位]的[整形(int)]类型,因此无法左移超过15位。因此 `1<<16` 的计算结果会错误地变成0。解决办法就是将类型改为[无符号长整形(unsigned long)]类型的 `1UL`。
+
+https://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`,请对照其电路图检查电路。
+
+- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf
+- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf
+
+Arduino Leonardo 以及 micro 使用的是**ATMega32U4**因此可以用TMK,但bootloader可能会是个麻烦的问题。
+
+## 启用JTAG
+
+默认情况下,键盘启动后JTAG调试接口就被禁用了。支持JTAG的MCU出场时会带着 `JTAGEN` 保险丝,而键盘因为需要这部分MCU的引脚去控制开关矩阵、LED等功能。
+
+如果你希望启用JTAG,在 `config.h` 中添加定义:
+
+```c
+#define NO_JTAG_DISABLE
+```
+
+## USB 3兼容性问题
+将设备从USB 3.x端口改插到USB 2.0端口能解决一些问题。
+
+
+## Mac相关兼容性问题
+### OS X 10.11 和 Hub
+参见: 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/docs/zh-cn/feature_grave_esc.md b/docs/zh-cn/feature_grave_esc.md
new file mode 100644
index 0000000000..f57dabeaff
--- /dev/null
+++ b/docs/zh-cn/feature_grave_esc.md
@@ -0,0 +1,39 @@
+# Grave Escape
+
+<!---
+ original document: 0.15.12:docs/feature_grave_esc.md
+ git diff 0.15.12 HEAD -- docs/feature_grave_esc.md | cat
+-->
+
+*译注:Grave键即标准键盘中Tab键上方的 <code>&#96;</code> 键,该符号用于英法语等西语体系,辅助调整发音,中文中没有对应概念;Escape即Esc键*
+
+若你使用60%或其它没有Fn键配列的键盘,会留意到没有独立的Escape键。Grave Escape功能可以让Grave键(<code>&#96;</code>及`~`)与Escape共享一个按键
+
+## 使用方法
+
+在配列中使用 `KC_GESC` 替换 `KC_GRAVE` (一般都在`1`键左边)。默认点击会输出 `KC_ESC`,按下Shift或GUI键时,点击会输出 `KC_GRV`
+
+## 操作系统视角
+
+假如翠花按下GESC键,系统接收到的是KC_ESC字符。若翠花按住Shift再按下GESC,将输出 `~` 或是反引号。若翠花按住GUI/CMD/Win键,将仅输出<code>&#96;</code>字符
+
+## 键码
+
+|键 |别名 |描述 |
+|---------|-----------|------------------------------------------------------------------|
+|`KC_GESC`|`GRAVE_ESC`|单击输出Escape, 按住Shift或GUI时输出<code>&#96;</code> |
+
+### 须留意
+
+在macOS上 Command+<code>&#96;</code>默认行为是“移动焦点到下一个窗口”,因此不会输出反引号。另外,即便在键盘配置中更改过快捷键,终端程序(Terminal)也通常会将这个操作视为循环切换窗口
+
+## 配置
+
+有几种键组合可以变更这种行为,如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/docs/zh-cn/feature_space_cadet.md b/docs/zh-cn/feature_space_cadet.md
new file mode 100644
index 0000000000..e3dab9c727
--- /dev/null
+++ b/docs/zh-cn/feature_space_cadet.md
@@ -0,0 +1,70 @@
+# Space Cadet: The Future, Built In
+<!-- Deliberately not translated, leave it to a suitable translation -->
+
+<!---
+ original document: 0.15.12:docs/feature_space_cadet.md
+ git diff 0.15.12 HEAD -- docs/feature_space_cadet.md | cat
+-->
+
+*译注:Space Cadet来源于(在西方早期程序员中)著名的键盘Space Cadet Keyboard,具体信息参见下面的链接或[维基百科](https://en.wikipedia.org/wiki/Space-cadet_keyboard)*
+
+Steve Losh 在 [Space Cadet Shift](https://stevelosh.com/blog/2012/10/a-modern-space-cadet/) 详细地描述了该功能. 简而言之,点击左Shift时,会输出左括号;点击右Shift时,会输出右括号。如果按住Shift键,常规的Shift将正常工作。这功能实际上和听起来的一样爽,更爽的是现在连Control和Alt也支持!
+
+## 使用指南
+
+首先,在你的配列中完成以下任一项:
+- 替换左Shift为 `KC_LSPO`(左Shift,左括号),替换右Shift为 `KC_RSPC`(右Shift,右括号)。
+- 替换左Control为 `KC_LCPO`(左Control,左括号),替换右Control为 `KC_RCPC`(右Control,右括号)。
+- 替换左Alt为 `KC_LAPO`(左Alt,左括号),替换右Alt为 `KC_RAPC`(右Alt,右括号)。
+- 替换任意一个Shift为 `KC_SFTENT`(右Shift,回车)。
+
+## 键码
+
+|键码 |描述 |
+|-----------|-----------------------------|
+|`KC_LSPO` |按住时左Shift,点击时 `(` |
+|`KC_RSPC` |按住时右Shift,点击时 `)` |
+|`KC_LCPO` |按住时左Control,点击时 `(` |
+|`KC_RCPC` |按住时右Control,点击时 `)` |
+|`KC_LAPO` |按住时左Alt,点击时 `(` |
+|`KC_RAPC` |按住时右Alt,点击时 `)` |
+|`KC_SFTENT`|按住时右Shift,点击时回车 |
+
+## 须留意
+
+同时按下两边的Shift键时会与Space Cadet功能冲突。请参见[指令功能](zh-cn/feature_command.md)以了解如何解决,也可以在 `rules.mk` 中禁用指令:
+
+```make
+COMMAND_ENABLE = no
+```
+
+## 配置
+
+默认情况下Space Cadet假设键盘布局为US ANSI,如果你的布局使用不同的括号符,可以在 `config.h` 中重定义。可以修改修饰键点击时发送的字符,亦或阻止修饰键工作。这个新的配置项依次绑定了三个键码:按住或组合其它键使用时的修饰键;点击时发送的修饰键点击(`Tap Modifier`)(在 `KC_TRNS` 中没有修饰键时);最后是点击时发送的键码。请记住,例如'KC_RSFT'按住时点击 `KC_KSPO` 及 `KC_TRNS` 时,修饰键依旧会对键码生效,即属于修饰键点击。
+
+|定义 |默认值 |描述 |
+|----------------|-------------------------------|----------------------------------------------------------------|
+|`LSPO_KEYS` |`KC_LSFT, LSPO_MOD, LSPO_KEY` |按住时发送`KC_LSFT`,点击时发送 `LSPO_MOD` 及 `LSPO_KEY` 定义的键码. |
+|`RSPC_KEYS` |`KC_RSFT, RSPC_MOD, RSPC_KEY` |按住时发送`KC_RSFT`,点击时发送 `RSPC_MOD` 及 `RSPC_KEY` 定义的键码. |
+|`LCPO_KEYS` |`KC_LCTL, KC_LSFT, KC_9` |按住时发送`KC_LCTL`,点击时发送 `KC_LSFT` 及 `KC_9`. |
+|`RCPC_KEYS` |`KC_RCTL, KC_RSFT, KC_0` |按住时发送`KC_RCTL`,点击时发送 `KC_RSFT` 及 `KC_0`. |
+|`LAPO_KEYS` |`KC_LALT, KC_LSFT, KC_9` |按住时发送`KC_LALT`,点击时发送 `KC_LSFT` 及 `KC_9`. |
+|`RAPC_KEYS` |`KC_RALT, KC_RSFT, KC_0` |按住时发送`KC_RALT`,点击时发送 `KC_RSFT` 及 `KC_0`. |
+|`SFTENT_KEYS` |`KC_RSFT, KC_TRNS, SFTENT_KEY` |按住时发送`KC_RSFT`,点击时发送 `SFTENT_KEY`. |
+|`SPACE_CADET_MODIFIER_CARRYOVER` |*未定义* |在尝试触发其它修饰键的修饰键点击前,暂存目前的修饰键。这在尝试触发Space Cadet前频繁发生修饰键提前松开时会有用。(译注[^1]) |
+
+
+## 过时的配置项
+
+以下是一些内部用于向后兼容的定义,目前仍可以使用,但上面的定义适用性要强得多。例如,若你点击 `KC_LSPO` 时不想按住修饰键,在旧定义中只有一个办法,使用 `DISABLE_SPACE_CADET_MODIFIER`。但现在可以定义为:`#define LSPO_KEYS KC_LSFT, KC_TRNS, KC_9`,效果是在按住按键时触发左Shift,点击则发送 `KC_9`。
+
+|定义 |默认值 |描述 |
+|------------------------------|-------------|-------------------------------------|
+|`LSPO_KEY` |`KC_9` |点击左Shift时发送的键码 |
+|`RSPC_KEY` |`KC_0` |点击右Shift时发送的键码 |
+|`LSPO_MOD` |`KC_LSFT` |应用在 `LSPO_KEY` 上的修饰键 |
+|`RSPC_MOD` |`KC_RSFT` |应用在 `RSPC_KEY` 上的修饰键 |
+|`SFTENT_KEY` |`KC_ENT` |点击Shift时发送的键码 |
+|`DISABLE_SPACE_CADET_MODIFIER`|*未定义* |定义时将阻止修饰键应用在Space Cadet上 |
+
+[^1]这句实在是绕,不能确保翻译到位,请参考英文文档
diff --git a/docs/zh-cn/flashing.md b/docs/zh-cn/flashing.md
new file mode 100644
index 0000000000..da3ceefc32
--- /dev/null
+++ b/docs/zh-cn/flashing.md
@@ -0,0 +1,329 @@
+# 刷写指引及Bootloader资料
+
+<!---
+ original document: 0.15.12:docs/flashing.md
+ git diff 0.15.12 HEAD -- docs/flashing.md | cat
+-->
+
+用于键盘的bootloader有很多种,几乎每一种都在使用私有的刷写协议及工具。幸运的是,形如[QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)这样的工程目标就是尽量支持这些工具,本文会探讨各种bootloader的差异,以及可用的刷写方案。
+
+针对基于AVR的键盘,QMK会自动检查所要刷写的 `.hex` 文件大小是否与在 `rules.mk` 中设置的 `BOOTLOADER` 值所匹配,同时会输出字节大小信息(及最大限制)。
+
+同时也可以使用CLI工具刷写键盘,执行:
+```
+$ qmk flash -kb <keyboard> -km <keymap>
+```
+更多信息参见文档[`qmk flash`](zh-cn/cli_commands.md#qmk-flash)。
+
+## Atmel DFU
+
+Atmel系列的DFU bootloader默认配备在所有USB AVR系列上(16/32U4RC除外),广泛用于一些PCB上具备私有集成电路模块(IC)的键盘上(老款OLKB、Clueboards等)。有些使用的是LUFA实现的DFU bootloader,或是QMK的分支版本(新款OLKB),后者对硬件功能进行了扩充加强。
+
+为保证对DFU bootloader的兼容性,请确保在 `rules.mk` 中存在如下部分内容(可选的值还有 `lufa-dfu` 或 `qmk-dfu`):
+
+```make
+# 选择Bootloader
+BOOTLOADER = atmel-dfu
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具)
+* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / QMK中将构建目标设为 `:dfu`(推荐的命令行工具)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码
+ * 如果PCB上有 `RESET` 键,点击之
+ * 快速短接一下RST到GND
+2. 等待操作系统识别到设备
+3. 清空flash存储数据(如果使用QMK工具箱或CLI的 `make`会自动进行)
+4. 将.hex文件刷写进去
+5. 重置设备进入应用模式(如上,会自动进行)
+
+### QMK DFU
+
+QMK维护了[一个LUFA DFU bootloader的分支版本](https://github.com/qmk/lufa/tree/master/Bootloaders/DFU),其可以进行一次矩阵扫描来退出bootloader进入应用模式,同时会让LED闪烁或蜂鸣器响一声。若要启用该功能,将以下定义添加到 `config.h`:
+
+```c
+#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW
+#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW
+// 可选:
+//#define QMK_LED E6
+//#define QMK_SPEAKER C6
+```
+目前来讲不推荐将 `QMK_ESC` 键设置成与[Bootmagic](zh-cn/feature_bootmagic.md)同一个键,否则按下该键时只会让MCU在bootloader模式上反复进出。
+
+制造商及型号字符串自动从 `config.h` 中获取,并会在型号后追加 " Bootloader"。
+
+要生成该bootloader,需指定 `bootloader` 构建目标,即 `make planck/rev4:default:bootloader`。要生成可部署到正式产品的.hex文件(同时包含QMK及bootloader),使用 `production` 构建目标,即 `make planck/rev4:default:production`。
+
+### `make` 构建目标
+
+* `:dfu`: 每5秒检测一次直到发现可用的DFU设备,然后进行固件刷写。
+* `:dfu-split-left` 和 `:dfu-split-right`: 同 `:dfu` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Elite-C的分体式键盘这是理想的方法。
+
+## Caterina
+
+Arduino及其仿制板使用[Caterina bootloader](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina)或某种变体(使用Pro Micro或其仿制芯片、Pololu A-Star等构建的所有键盘),并基于虚拟串口使用AVR109协议进行通信。
+
+为确保对Caterina bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = caterina
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具)
+* [avrdude](https://www.nongnu.org/avrdude/) QMK中须基于 `avr109` 编程器 / `:avrdude` 构建目标 (推荐的命令行工具)
+* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写;一些型号需要你在750ms内重置两次):
+ * 点击 `RESET` 键码
+ * 如果PCB上有 `RESET` 键,点击之
+ * 快速短接一下RST到GND
+2. 等待操作系统识别到设备
+3. 将.hex文件刷写进去
+4. 等待设备自动重置
+
+### `make` 构建目标
+
+* `:avrdude`: 每5秒检测一次直到发现可用的Caterina设备(通过检测新COM端口),然后进行固件刷写。
+* `:avrdude-loop`: 同 `:avrdude` 一样刷写固件,但会在一个设备刷写完后再次尝试刷写。主要用于批量刷写设备。按 Ctrl+C 以终止循环检测。
+* `:avrdude-split-left` 和 `:avrdude-split-right`: 同 `:avrdude` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Pro Micro的分体式键盘这是理想的方法。
+
+## HalfKay
+
+HalfKay是一款由PJRC开发的超精简的bootloader,且呈现为HID设备(因此不需要额外的驱动),在所有的Teensys,即"the 2.0",上已经预刷写过。该bootloader目前是闭源的,因此一旦覆写(即通过ISP刷入其它bootloader)掉,就无法复原了。
+
+为确保对Halfkay bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = halfkay
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具)
+* [Teensy Loader Command Line](https://www.pjrc.com/teensy/loader_cli.html) / QMK中将构建目标设为 `:teensy`(推荐的命令行工具)
+* [Teensy Loader](https://www.pjrc.com/teensy/loader.html)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写):
+ * 点击 `RESET` 键码
+ * 如果Teensy上或PCB上有 `RESET` 键,点击之
+ * 快速短接一下RST到GND
+2. 等待操作系统识别到设备
+3. 将.hex文件刷写进去
+4. 重置设备进入应用模式(可能会自动进行)
+
+## USBasploader
+
+USBasploader是一款来源于[Objective Development](https://www.obdev.at/products/vusb/usbasploader.html)的bootloader。它通过模拟出一个USBasp ISP编程器来运行V-USB以用于一些形如ATmega328P这样的“非USB AVR芯片”。
+
+为确保对USBasploader bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = usbasploader
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具)
+* [avrdude](https://www.nongnu.org/avrdude/) QMK中须基于 `usbasp` 编程器 / `:usbasp` 构建目标(推荐的命令行工具)
+* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码
+ * 在按住 `BOOT` 按钮时,快速点击一下PCB上的 `RESET`
+2. 等待操作系统识别到设备
+3. 将.hex文件刷写进去
+4. 点击PCB上的 `RESET` 按钮或将RST短接至GND一下。
+
+## BootloadHID
+
+BootloadHID是一款用于AVR微控制器的bootloader,其呈现为HID输入设备,和HalkKay很像,因此在Windows下也无需安装驱动。
+
+为确保对bootloadHID bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = bootloadhid
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具)
+* [bootloadHID CLI](https://www.obdev.at/products/vusb/bootloadhid.html) / QMK中将构建目标设为 `:bootloadhid`(推荐的命令行工具)
+* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash)
+
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码
+ * 在按住“盐键”(salt key)时插入键盘 - 在PS2AVRGB板上,通常在MCU的A0及B0引脚上有这个按键,否则请查看键盘的使用说明。
+2. 等待操作系统识别到设备
+3. 将.hex文件刷写进去
+4. 重置设备到应用模式(可能会自动进行)
+
+### QMK HID
+
+QMK维护了[一个LUFA HID bootloader的分支版本](https://github.com/qmk/lufa/tree/master/Bootloaders/HID),通过USB HID节点设备进行刷写,工作模式类似于PJRC的Teensy Loader刷写器以及HalfKay bootloader。其可以进行一次矩阵扫描来退出bootloader进入应用模式,同时会让LED闪烁或蜂鸣器响一声。
+
+为确保对QMK HID bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = qmk-hid
+```
+
+要启用额外的功能支持,请添加如下定义至 `config.h`:
+
+```c
+#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW
+#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW
+// 可选:
+//#define QMK_LED E6
+//#define QMK_SPEAKER C6
+```
+
+目前来讲不推荐将 `QMK_ESC` 键设置成与[Bootmagic Lite](zh-cn/feature_bootmagic.md)同一个键,否则按下该键时只会让MCU在bootloader模式上反复进出。
+
+制造商及型号字符串自动从 `config.h` 中获取,并会在型号后追加 " Bootloader"。
+
+要生成该bootloader,需指定 `bootloader` 构建目标,即 `make planck/rev4:default:bootloader`。要生成可部署到正式产品的.hex文件(同时包含QMK及bootloader),使用 `production` 构建目标,即 `make planck/rev4:default:production`。
+
+兼容的刷写工具:
+
+* TBD
+ * 目前只能选择使用该 [Python脚本](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp_python), 或从LUFA仓库中构建[`hid_bootloader_cli`](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp)。Homebrew也许(即将)能直接支持(通过 `brew install qmk/qmk/hid_bootloader_cli`)。
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码
+ * 如果PCB上有 `RESET` 键,点击之
+ * 快速短接一下RST到GND
+2. 等待操作系统识别到设备
+4. 将.hex文件刷写进去
+5. 重置设备进入应用模式(可能会自动进行)
+
+### `make` 构建目标
+
+* `:qmk-hid`: 每5秒检测一次直到发现可用的DFU设备,然后进行固件刷写。
+
+## STM32/APM32 DFU
+
+所有的STM32及APM32 MCU系列,除F103型号外(参见[STM32duino小节](#stm32duino))都在出场时预装了bootloader且无法修改或删除。
+
+为确保对STM32-DFU bootloader的兼容性,请添加如下代码块至 `rules.mk`(可选替代项为 `apm32-dfu`):
+
+```make
+# 选择Bootloader
+BOOTLOADER = stm32-dfu
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具)
+* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写):
+ * 点击 `RESET` 键码(对STM32F042设备可能无效)
+ * 如果有重置电路,点击PCB上的 `RESET` 键;有些主控板上可能会有一个开关需要先打开
+ * 否则,你需要将 `BOOT0` 接线到VCC(通过 `BOOT0` 按钮或跳线),短接 `RESET` 至GND(通过 `RESET` 按钮或条线),然后断开 `BOOT0` 的接线。
+2. 等待操作系统识别到设备
+3. 将.bin文件刷写进去
+4. 重置设备进入应用模式(可能会自动进行)
+
+### `make` 构建目标
+
+* `:dfu-util`: 每5秒检测一次直到发现可用的STM32 bootloader设备,然后进行固件刷写。
+* `:dfu-util-split-left` 和 `:dfu-util-split-right`: 同 `:avrdude` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Proton-C的分体式键盘这是理想的方法。
+* `:st-link-cli`: 通过ST-Link CLI工具集而非dfu-util进行刷写,需要有ST-Link电子狗。
+* `:st-flash`: 通过[STLink工具](https://github.com/stlink-org/stlink)内的 `st-flash` 工具而非dfu-util进行刷写,需要有ST-Link电子狗。
+
+## STM32duino :id=stm32duino
+
+该bootloader几乎是STM32F103板专用,该型号出厂不带USB DFU bootloader。其源代码及预编译好的二进制文件[在这里](https://github.com/rogerclarkmelbourne/STM32duino-bootloader)。
+
+为确保对STM32duino bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = stm32duino
+```
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具)
+* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写):
+ * 点击 `RESET` 键码(对STM32F042设备可能无效)
+ * 如果有重置电路,点击PCB上的 `RESET` 键;有些主控板上可能会有一个开关需要先打开
+ * 否则,你需要将 `BOOT0` 接线到VCC(通过 `BOOT0` 按钮或跳线),短接 `RESET` 至GND(通过 `RESET` 按钮或条线),然后断开 `BOOT0` 的接线。
+2. 等待操作系统识别到设备
+3. 将.bin文件刷写进去
+4. 重置设备进入应用模式(可能会自动进行)
+
+## Kiibohd DFU
+
+Input Club出品的键盘使用NXP Kinetis微控制器而非STM32,并使用了独有的[自制bootloader](https://github.com/kiibohd/controller/tree/master/Bootloader),然而处理器 及协议上两者大部分是一致的。
+
+在 `rules.mk` 中该bootloader的设置项为 `kiibohd`,但既然该bootloader仅用在Input Club主控板上,就不必要设置到键映射或是用户级<!--译:不清楚这里的“user level”是个啥……-->了。
+
+兼容的刷写工具:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具)
+* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具)
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码(有可能只能进入到“安全”bootloader模式,参见[这里](https://github.com/qmk/qmk_firmware/issues/6112))
+ * 如果PCB上有 `RESET` 键,点击之
+2. 等待操作系统识别到设备
+3. 将.bin文件刷写进去
+4. 重置设备进入应用模式(可能会自动进行)
+
+## tinyuf2
+
+键盘可以考虑支持tinyuf2 bootloader,目前唯一支持的设备是F401/F411 blackpill。
+
+在 `rules.mk` 中该bootloader的设置项为 `tinyuf2`,也可指定到键映射及用户级中。
+
+为确保对tinyuf2 bootloader的兼容性,请添加如下代码块至 `rules.mk`:
+
+```make
+# 选择Bootloader
+BOOTLOADER = tinyuf2
+```
+
+兼容的刷写工具:
+
+* 任何具备文件拷贝能力的程序,如 _macOS Finder_ 或 _Windows Explorer_ *。
+
+刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码
+ * 双击PCB上的 `nRST` 键
+2. 等待操作系统识别到设备
+3. 将.uf2文件拷贝到新出现的USB存储设备上
+4. 等待设备恢复可用状态
diff --git a/docs/zh-cn/flashing_bootloadhid.md b/docs/zh-cn/flashing_bootloadhid.md
new file mode 100644
index 0000000000..70139c1e12
--- /dev/null
+++ b/docs/zh-cn/flashing_bootloadhid.md
@@ -0,0 +1,75 @@
+# BootloadHID刷写指引及资料
+
+<!---
+ original document: 0.15.12:docs/flashing_bootloadhid.md
+ git diff 0.15.12 HEAD -- docs/flashing_bootloadhid.md | cat
+-->
+
+ps2avr(GB)基于一片ATmega32A微控制器及特殊的bootloader,无法使用常规的QMK方法进行刷写。
+
+常规刷写过程:
+
+1. 使用如下任一方式进入bootloader模式:
+ * 点击 `RESET` 键码(一些设备上不管用)
+ * 在按住“盐键”(salt key)时插入键盘(该键一般会在键盘使用说明上写明)
+2. 等待操作系统识别到设备
+3. 将.hex文件刷写进去
+4. 重置设备到应用模式(可能会自动进行)
+
+## 用于bootloadHID刷写的构建目标
+
+?> 使用QMK安装脚本,具体[参见这里](zh-cn/newbs_getting_started.md),所需的bootloadHID工具应自动被安装上。
+
+若希望通过命令行进行刷写,通过如下命令指定 `:bootloadhid` 构建目标:
+
+ make <keyboard>:<keymap>:bootloadhid
+
+## 基于图形化界面的刷写方法
+
+### Windows
+1. 下载[HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash)
+2. 重置键盘
+3. 确认VID为 `16c0` 且PID为 `05df`
+4. 点击 `查找设备(Find Device)` 并确认目标键盘可见
+5. 点击 `打开.hex文件(Open .hex File)` 并定位到你创建的.hex文件
+6. 点击 `刷写设备(Flash Device)` 并等待刷写完毕
+
+## 在命令行中进行刷写
+
+1. 重置键盘
+2. 通过输入 `bootloadHID -r` 并追加 `.hex` 文件的路径进行主控板的刷写
+
+### Windows系统上手动安装
+针对MSYS2:
+1. 下载BootloadHID固件包:https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz
+2. 使用合适的工具解压,如7-Zip
+3. 将解压出的 `commandline/bootloadHID.exe` 拷贝至MSYS目录下,一般是 `C:\msys64\usr\bin`
+
+针对Windows本地环境刷写,`bootloadHID.exe` 可以直接在非MSYS2环境下执行。
+
+### Linux系统上手动安装
+1. 安装libusb开发依赖项:
+ ```bash
+ # 该操作具体取决于系统 - 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/docs/zh-cn/getting_started_docker.md b/docs/zh-cn/getting_started_docker.md
new file mode 100644
index 0000000000..038f17f9ac
--- /dev/null
+++ b/docs/zh-cn/getting_started_docker.md
@@ -0,0 +1,59 @@
+# Docker快速上手指引
+
+<!---
+ original document: 0.15.12:docs/getting_started_docker.md
+ git diff 0.15.12 HEAD -- docs/getting_started_docker.md | cat
+-->
+
+本工程包含了一套Docker工作流,可以方便地在不更改你主系统环境情况下完成新固件文件的构建工作。这同时也保证了在你拉取该工程代码后的编译环境与其他人以及QMK开发者的一致。当你需要其他人协助你排查遇到的问题时会方便很多。
+
+## 需求
+
+核心需求是一个已安装的可用的 `docker` 或 `podman`。
+* [Docker CE](https://docs.docker.com/install/#supported-platforms)
+* [Podman](https://podman.io/getting-started/installation)
+
+## 用法
+
+拉取QMK仓库到本地(包括所有的子模块):
+
+```bash
+git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git
+cd qmk_firmware
+```
+
+执行以下命令构建键映射:
+```bash
+util/docker_build.sh <keyboard>:<keymap>
+# 例: util/docker_build.sh planck/rev6:default
+```
+
+如上可以构建所需的键盘/键映射,可用于刷写的 `.hex` 及 `.bin` 输出文件存放在QMK目录下。如果省略了 `:keymap` 参数,所有的键映射都会被编译。留意编译参数格式与 `make` 构建时的一致。
+
+同时也支持直接从Docker中编译和刷写,只需要指定 `target`:
+
+```bash
+util/docker_build.sh keyboard:keymap:target
+# 例: util/docker_build.sh planck/rev6:default:flash
+```
+
+可以不带参数地执行该脚本,其会依次要求你输入这些参数,也许你会觉得这样更好用:
+
+```bash
+util/docker_build.sh
+# 从输入中读取参数 (留空则构建所有的键盘/键映射)
+```
+
+可以通过设置环境变量 `RUNTIME` 为想使用的容器运行时的名称或路径来指定运行时,默认其会检测并自动选取docker或podman,相比于podman会更倾向于用docker。
+
+```bash
+RUNTIME="podman" util/docker_build.sh keyboard:keymap:target
+```
+
+## FAQ
+
+### 为什么我无法在我的Windows/macOS下刷写固件
+
+在Windows及macOS上,需要有[Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/)运行着,配置过程很繁琐,因此我们没有做推荐。请考虑使用[QMK工具箱](https://github.com/qmk/qmk_toolbox)。
+
+!> Windows下需要启用[Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)才能运行Docker,这也意味着它无法运行在没有Hyper-V的Windows版本下,如Windows 7,Windows 8及**Windows 10家庭版**。
diff --git a/docs/zh-cn/getting_started_getting_help.md b/docs/zh-cn/getting_started_getting_help.md
deleted file mode 100644
index 8c0ebaa243..0000000000
--- a/docs/zh-cn/getting_started_getting_help.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# 获得帮助
-
-有很多方法来获得关于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/docs/zh-cn/getting_started_github.md b/docs/zh-cn/getting_started_github.md
index b4e8e9fa5d..2a5ec8ca4f 100644
--- a/docs/zh-cn/getting_started_github.md
+++ b/docs/zh-cn/getting_started_github.md
@@ -1,6 +1,11 @@
# 如何在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.
+<!---
+ original document: 0.15.12:docs/getting_started_github.md
+ git diff 0.15.12 HEAD -- docs/getting_started_github.md | cat
+-->
+
+对不熟悉 GitHub 的人来说,使用GitHub 可能会有些难度。此教程会教您 fork 和 clone QMK,以及向 QMK 提交 pull request 。
?> 本教程假设您已安装GitHub,并且您喜欢使用命令行工作。
diff --git a/docs/zh-cn/getting_started_introduction.md b/docs/zh-cn/getting_started_introduction.md
index b977b63390..82d50355eb 100644
--- a/docs/zh-cn/getting_started_introduction.md
+++ b/docs/zh-cn/getting_started_introduction.md
@@ -1,5 +1,10 @@
# 介绍
+<!---
+ original document: 0.15.12:docs/getting_started_introduction.md
+ git diff 0.15.12 HEAD -- docs/getting_started_introduction.md | cat
+-->
+
本页解释了使用QMK项目所需的基本信息。它假定您能熟练使用Unix shell,但您不熟悉C语言也不熟悉使用make编译。
## 基本QMK结构
@@ -8,7 +13,7 @@ QMK是[Jun Wako](https://github.com/tmk)的[tmk_keyboard](https://github.com/tmk
### 用户空间结构
-在`users`文件夹里面的目录是每个用户的目录。这个文件夹里面放的是用户们在不同键盘都能用到的代码。详见[用户空间特性](feature_userspace.md)
+在`users`文件夹里面的目录是每个用户的目录。这个文件夹里面放的是用户们在不同键盘都能用到的代码。详见[用户空间特性](zh-cn/feature_userspace.md)
### 键盘项目结构
@@ -25,7 +30,7 @@ QMK是[Jun Wako](https://github.com/tmk)的[tmk_keyboard](https://github.com/tmk
* `config.h`: 配置布局的选项
* `keymap.c`: 布局的全部代码, 必要文件
* `rules.mk`: 使能的QMK特性
-* `readme.md`:介绍你的布局,告诉别人怎么使用,附上功能说明。请将图片上传到imgur等图床(译者注:imgur可能已被墙,为了方便国人访问,建议使用国内可以直接访问的图床)。
+* `readme.md`:介绍你的布局,告诉别人怎么使用,附上功能说明。请将图片上传到imgur等图床(译注:imgur可能已被墙,为了方便国人访问,建议使用国内可以直接访问的图床)。
# `config.h` 文件
diff --git a/docs/zh-cn/getting_started_vagrant.md b/docs/zh-cn/getting_started_vagrant.md
new file mode 100644
index 0000000000..5e5de44552
--- /dev/null
+++ b/docs/zh-cn/getting_started_vagrant.md
@@ -0,0 +1,61 @@
+# Vagrant快速上手指引
+
+<!---
+ original document: 0.15.12:docs/getting_started_vagrant.md
+ git diff 0.15.12 HEAD -- docs/getting_started_vagrant.md | cat
+-->
+
+本工程包含一份 `Vagrantfile`,可以方便地在不更改你系统环境情况下完成新固件文件的构建工作。这同时也保证了在你拉取该工程代码后的编译环境与也使用Vagrantfile的其它人的一致。当你需要其他人协助你排查遇到的问题时会方便很多。
+
+## 需求
+
+本工程中的 `Vagrantfile` 需要安装[Vagrant](https://www.vagrantup.com/)以及可用的虚拟机服务:
+
+* [VirtualBox](https://www.virtualbox.org/) (5.0.12及以后版本)
+ * 卖点是'最适用于Vagrant的平台'
+* [VMware Workstation](https://www.vmware.com/products/workstation) 及 [Vagrant VMware插件](https://www.vagrantup.com/vmware)
+ * (付费购买的)VMware插件需要在经过正版授权的VMware Workstation/Fusion上运行
+* [Docker](https://www.docker.com/)
+
+安装了Vagrant之后,在安装合适的虚拟机服务后可能需要重启机器。拉取本工程后在工程目录下执行 'vagrant up' 将启动一个包含了所有本工程所需工具的构建环境(虚拟机或是容器)。最后会有一个vagrant启动提示告知你一切正常就绪,否则你也可以参考一下下面的构建文档。
+
+## 刷写固件
+
+比较“简单”的方案是在你的宿主系统上借助以下工具刷写固件:
+
+* [QMK工具箱](https://github.com/qmk/qmk_toolbox) (推荐)
+* [Teensy Loader](https://www.pjrc.com/teensy/loader.html)
+
+如果你希望通过命令行进行编程工作,可以在Vagrantfile中取消掉['modifyvm']的注释以允许USB直通到Linux环境,既可以使用dfu-util/dfu-programmer之类的命令行工具进行编程工作,或是安装Teensy的命令行版本。
+
+## Vagrantfile概览
+开发环境被配置为运行QMK Docker镜像 `qmkfm/qmk_cli`,不仅让各系统下的功能预期一致,也是我们CI环境的镜像。
+
+## FAQ
+
+### 为什么我的VirtualBox环境会有问题?
+VirtualBox 5的某些版本与工程中Vagrantfile中指定的VirtualBox扩展存在兼容问题。如果你遇到了/vagrant挂载不成功的问题,请升级VirtualBox至5.0.12或更高版本。**或者,可以尝试执行如下命令:**
+
+```console
+vagrant plugin install vagrant-vbguest
+```
+
+### 如何移除一个现有环境?
+不再需要这个环境了是吗?在本工程目录下的任何位置,执行:
+
+```console
+vagrant destroy
+```
+
+### 如果我是想直接用Docker呢?
+想在不使用虚拟机技术的情况下也能使用Vagrant工作流?Vagrangfile已配置为允许绕过运行虚拟机,直接运行容器。通过如下方式执行命令可以强制使用Docker来启动环境:
+```console
+vagrant up --provider=docker
+```
+
+### 如何访问虚拟机环境而非Docker容器?
+通过如下方法跳过 `vagrant` 的用户初始化过程以在QMK构建镜像中直接执行:
+
+```console
+vagrant ssh -c 'sudo -i'
+```
diff --git a/docs/zh-cn/keymap.md b/docs/zh-cn/keymap.md
new file mode 100644
index 0000000000..b4433ed49f
--- /dev/null
+++ b/docs/zh-cn/keymap.md
@@ -0,0 +1,209 @@
+# 键映射总览
+
+<!---
+ original document: 0.15.12:docs/keymap.md
+ git diff 0.15.12 HEAD -- docs/keymap.md | cat
+-->
+
+QMK键映射定义在C源文件中,其数据结构上是一个容纳了数组的数组。外层数组容纳了各个层,内层各数组则为层内的键列表。基本所有键盘都通过定义 `LAYOUT()` 宏来创建该两级数组。
+
+
+## 键映射与配列 :id=keymap-and-layers
+在QMK中, **`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`** 容纳了多个 **层**, 每个**层**下包含了由**16位**的**动作码**所组成的键映射信息。 最多可以定义**32个层**。
+
+对于常规键的定义,其**动作码**的高8位皆为0,低8位保存了USB HID中使用的各个键对应的**键码**。
+
+不同的层可以同时生效,层的编号从0至31,编号越高的层优先级越高。
+(译注:由于是ascii图,掺杂中文会导致排版错乱,各翻译标注在图下方。下同)
+
+ 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 `--------------------------
+翻译:
+
+|原文 |译文 |
+|--------------------------|-------------|
+|Keymap: 32 Layers | 键映射:32个层|
+|stack of layers | 层堆栈 |
+|precedence | 优先级 |
+|high/low | 高/低 |
+|layer: action code matrix | 层:动作码矩阵|
+|row/column | 行/列 |
+
+有时,键映射中存储的动作码在一些文档中也被称作键码,主要是由TMK沿袭而来的习惯。
+
+### 键映射的层状态 :id=keymap-layer-status
+
+键映射的层状态由两个32位参数决定:
+
+* **`default_layer_state`** 指向一个总是可用的键映射层(0-31)(即默认层)。
+* **`layer_state`** 每一位标记对应层的启用/停用状态。
+
+通常键映射中的'0'层为 `default_layer(默认层)`,其它层在启动时会被固件置为停用状态,不过这些可以通过 `config.h` 进行配置。当你换了一个按键布局时可用于更改 `default_layer`,比如从Qwerty布局切换到了Colemak布局。
+
+ 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
+翻译:
+
+|原文 |译文 |
+|-----------------------|-------------|
+|Initial state of Keymap| 键映射原始状态|
+|Change base layout | 更改了基础层 |
+
+另外,可以通过修改 `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`(穿透)键码,就会停止查找,再往下的层级不会被查看。
+
+ ____________
+ / / <--- 较高的层
+ / KC_TRNS //
+ /___________// <--- 较低的层 (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` 文件中会有三个你可能会关心的部分:
+
+* [预定义](#definitions)
+* [层/键映射数据结构](#layers-and-keymaps)
+* [自定义函数](#custom-functions),若有的话
+
+### 预定义
+
+文件头部可以看到:
+
+ #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) *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ // 译:可以用 _______ 替代 KC_TRNS(穿透),用 XXXXXXX 替代 KC_NO (空操作)
+
+ // 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.
+ // 译:每一层为了便于识别可以起一个名字,下划线没有实际意义 - 叫STUFF之类的也行的,
+ // 译:层名不需要都一样长,甚至不定义这些直接用层号也是可以的
+ #define _BL 0
+ #define _FL 1
+ #define _CL 2
+
+以上是一些便于编写键映射及自定义函数时可用的预定义,`GRAVE_MODS` 后续会用在自定义函数中,之后的 `_BL`, `_FL` 及 `_CL` 便于我们在代码中引用这些层。
+
+注:在一些更早的键映射文件中,你可能会发现一些形如 `_______` 或 `XXXXXXX` 的定义,这些可以分别代替 `KC_TRNS` 及 `KC_NO`,这样可以更清楚地分辨出各层中定义了哪些键的键值。现在这些定义是不需要的,因为我们默认已经提供了这些定义。
+
+### 层和键映射
+
+这个文件中最主要的部分是 `keymaps[]` 定义,这里须列出你的层以及层中的内容。这一部分应该以如下定义起始:
+
+ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+之后是一个LAYOUT()宏组成的列表,一个LAYOUT()下定义了一个层中的键列表,一般你需要至少一个“基础层”(如QWERTY、Dvorak或Colemak),之后是在其之上的多个“功能”层。受限于对层的处理顺序,较低的层无法覆盖在较高的层上。
+
+QMK在 `keymaps[][MATRIX_ROWS][MATRIX_COLS]` 中保存着16位的动作码(有些时候也被称作键码),对于与常规键一致的键码,其高字节为0,低字节为USB HID 键盘所使用的键码值。
+
+> 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`, 以便凸显在该层中有变化的那些键。
+* 对于这一层来讲,如果点击的是一个 `_______` 键,实际生效的将是其下的活跃层中的键。
+
+# 核心细节
+
+在阅读完本节后,你应该掌握了构建自己的键映射的基础能力,更多的资料请参见:
+
+* [键码](zh-cn/keycodes.md)
+* [键映射FAQ](zh-cn/faq_keymap.md)
+
+我们仍在优化这份文档,如果你有更好的优化建议,请[提交一份issue](https://github.com/qmk/qmk_firmware/issues/new)!
diff --git a/docs/zh-cn/mod_tap.md b/docs/zh-cn/mod_tap.md
new file mode 100644
index 0000000000..5bf18a1527
--- /dev/null
+++ b/docs/zh-cn/mod_tap.md
@@ -0,0 +1,143 @@
+# Mod-Tap
+
+<!---
+ original document: 0.15.12:docs/mod_tap.md
+ git diff 0.15.12 HEAD -- docs/mod_tap.md | cat
+-->
+
+Mod-Tap键 `MT(mod, kc)` 在按住时功能为修饰键,在点击时则是常规键码。举例来讲,可以设计出一个按键,当点击时发送Escape,按下时则作为Control或Shift
+
+修饰键码及`OSM()`将会被缀以`MOD_`前缀,而非`KC_`
+
+|修饰键码 |描述 |
+|----------|------------------------------------------|
+|`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同时按下) |
+
+可以通过逻辑或进行组合:
+
+```c
+MT(MOD_LCTL | MOD_LSFT, KC_ESC)
+```
+
+此时按住该键将触发左Control及左Shift,点击将发送Escape。
+
+为了方便配列,QMK已包含一些常见的Mod-Tap:
+
+|键 |别名 |描述 |
+|------------|-----------------------------------------------------------------|---------------------------------------------|
+|`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` |
+|`LSG_T(kc)` |`SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` |按住时为左Shift及GUI,点击时为 `kc` |
+|`LAG_T(kc)` | |按住时为左Alt及GUI,点击时为 `kc` |
+|`RSG_T(kc)` | |按住时为右 Shift及GUI,点击时为 `kc` |
+|`RAG_T(kc)` | |按住时为右 Alt及GUI,点击时为 `kc` |
+|`LCA_T(kc)` | |按住时为左Control及Alt,点击时为 `kc` |
+|`LSA_T(kc)` | |按住时为左Shift及Alt,点击时为 `kc` |
+|`RSA_T(kc)` |`SAGR_T(kc)` |按住时为右 Shift及右 Alt (AltGr),点击时为 `kc` |
+|`RCS_T(kc)` | |按住时为右 Control及右 Shift,点击时为 `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` - 更多[参见这里](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)|
+
+## 注意
+
+目前 `MT()` 的 `kc`参数限制在[基础键码集](zh-cn/keycodes_basic.md)中,因此不能使用 `LCTL()`,`KC_TILD` 及其它大于 `0xFF` 的键码。原因是,QMK使用16位的键码,其中3位是功能标记,1位标记左右修饰键,4位存储修饰键码,仅剩8位存储键码。当一次Mod-Tap触发时,只要有一个右修饰键被激发,其它的修饰键也都被视为右修饰键,因此无法混搭形如左Control+右Shift的形式,会被视为右Control+右Shift
+
+若展开讲就比较复杂了。迁移到32位的键码可以很大程度解决这个问题,但同时会招致配列矩阵大小翻倍,也可能会有其它未知问题。若是想用修饰键配合按键,可以考虑使用[Tap Dance/多击键](zh-cn/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys)
+
+在使用Windows远程桌面时你可能会发现有些问题,这是因为远程桌面对键码响应过快。若要修复,可以打开远程桌面的“配置”,在“本地资源”页中的键盘属性,调整为“本地计算器”,此时功能即可恢复正常。另一个办法是加大[`TAP_CODE_DELAY`](zh-cn/config_options.md#behaviors-that-can-be-configured)。
+
+## 截获Mod-Taps
+
+### 改变点击功能
+
+若要在Mod-Tap中突破基础键码的限制,可以在 `process_record_user` 中实现。如,上档键码 `KC_DQUO` 无法与 `MT()` 共用,因为它实际上是 `LSFT(KC_QUOT)` 的别名,`KC_DQUO` 上的修饰键码会被 `MT()` 覆盖。但可以使用如下代码截获点击,手动发送 `KC_DQUO`:
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case LCTL_T(KC_DQUO):
+ if (record->tap.count && record->event.pressed) {
+ tap_code16(KC_DQUO); // 点击时发送 KC_DQUO
+ return false; // 通过返回false阻止对该键的其它处理
+ }
+ break;
+ }
+ return true;
+}
+```
+
+### 改变按住功能
+
+类似地,同样可以使用这段自定义代码改变按住功能。下面的例子会在 `LT(0, kc)` (layer-tap键无实际意义,因为layer 0默认被激活)按住时对X,C和V键附加剪切,复制和粘贴功能:
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case LT(0,KC_X):
+ if (record->tap.count && record->event.pressed) {
+ return true; // 返回true来发送常规键码
+ } else if (record->event.pressed) {
+ tap_code16(C(KC_X)); // 截获按住功能来发送Ctrl-X
+ }
+ return false;
+ case LT(0,KC_C):
+ if (record->tap.count && record->event.pressed) {
+ return true; // 返回true来发送常规键码
+ } else if (record->event.pressed) {
+ tap_code16(C(KC_C)); // 截获按住功能来发送Ctrl-C
+ }
+ return false;
+ case LT(0,KC_V):
+ if (record->tap.count && record->event.pressed) {
+ return true; // 返回true来发送常规键码
+ } else if (record->event.pressed) {
+ tap_code16(C(KC_V)); // 截获按住功能来发送Ctrl-V
+ }
+ return false;
+ }
+ return true;
+}
+```
+
+在数字及字母键上使用Mod-Tap时推荐启用 `IGNORE_MOD_TAP_INTERRUPT`,以避免在快速按下下一个键时保持功能优先级。参见[忽略Mod Tap中断](zh-cn/tap_hold.md#ignore-mod-tap-interrupt)。
+
+### 同时改变点击和按住功能
+
+最后一个例子通过 `LT(0,KC_NO)` 实现了点击复制,按住粘贴的功能:
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case LT(0,KC_NO):
+ if (record->tap.count && record->event.pressed) {
+ tap_code16(C(KC_C)); // 截获点击来发送Ctrl-C
+ } else if (record->event.pressed) {
+ tap_code16(C(KC_V)); // 截获按住功能来发送Ctrl-V
+ }
+ return false;
+ }
+ return true;
+}
+```
+
+## 其它信息
+
+在[点按配置](zh-cn/tap_hold.md)中描述了影响Mod-Tap行为的标记。
diff --git a/docs/zh-cn/newbs.md b/docs/zh-cn/newbs.md
index eca8c14e5f..3be4626211 100644
--- a/docs/zh-cn/newbs.md
+++ b/docs/zh-cn/newbs.md
@@ -1,23 +1,29 @@
-# QMK菜鸟教程
+# QMK入门教程
-QMK是为你机械硬盘设计的的一个强大的开源固件。使用QMK可以很简单的让你的定制键盘变得强大。看完这篇文章,无论你是菜鸟还是大佬,都可以顺利的使用QMK来定制键盘。
+<!---
+ original document: 0.15.12:docs/newbs.md
+ git diff 0.15.12 HEAD -- docs/newbs.md | cat
+-->
-你是否为不知道你的键盘能不能运行QMK而苦恼? 如果你的机械键盘是你自己做的,那么这把键盘一般可以运行QMK。我们提供了[一大堆自制键盘](https://qmk.fm/keyboards/), 所以即便你的键盘不能运行QMK你也很容易能找到满足你需求的键盘。
+就像计算机一样,每把键盘里也有一个处理器,它的职责是在你点击键盘时,检测到这个动作并反馈给计算机。QMK固件即是为了这个目的而设计的一种"软件",负责检测点击,反馈给电脑。当你构建出一个自定义键映射时,就是在创建一个新的键盘"软件"。
-## 概览
+QMK的愿景是提供强有力的功能,让不可能的事情变得可能,简单的事情依旧简单。即便是不会编程也可以创建强大的键映射方案。
-这个教程有7个主要部分:
+想知道你的键盘是否能运行QMK?如果这个键盘是你自己组建的,那么很可能是可以的。我们[已经支持很多键盘](https://qmk.fm/keyboards/),所以即便你的键盘不能运行QMK,你也很容易能买到满足要求的键盘。
-* [新手上路](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)
+?> **这份指南适合于我吗?**<br>
+编程对你是个困难的话,可以看看我们的[在线GUI页面](zh-cn/newbs_building_firmware_configurator.md)。</div>
-这份教程旨在帮助没有固件构建经验的人,也是根据该目的做出选择和建议。这些程序有很多替代方法,大部分替代我们都支持。如果你对完成一个任务有疑问,可以[向我们寻求帮助](getting_started_getting_help.md).
+## 总览
-## 其他资源
+这份指南适用于想通过源代码编译出键盘固件的需求。对于程序员,全过程都会感觉很熟悉。教程主要分3部分:
-* [Thomas Baart的 QMK基础博客](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 这是一个用户创建的博客,涵盖了为新手准备的使用QMK的基础知识。
+1. [环境配置](zh-cn/newbs_getting_started.md)
+2. [构建第一个固件](zh-cn/newbs_building_firmware.md)
+3. [刷写固件](zh-cn/newbs_flashing.md)
+
+该指南的目的是帮助那些从未编译过软件的人,很多取舍及建议都是基于这个考量。完成一个目标可能有多种方案,我们尽量都去支持,如果你搞不明白你的目标如何实现,可以[向我们寻求帮助](zh-cn/support.md)。
+
+## 更多资料
+
+这份指南之外,也有一些其它能帮助你学习QMK的资料。我们归纳整理在[大纲](zh-cn/syllabus.md)页面和[学习资料](zh-cn/newbs_learn_more_resources.md)页面
diff --git a/docs/zh-cn/newbs_best_practices.md b/docs/zh-cn/newbs_best_practices.md
deleted file mode 100644
index fa58dc75e8..0000000000
--- a/docs/zh-cn/newbs_best_practices.md
+++ /dev/null
@@ -1,163 +0,0 @@
-# 最佳实践
-
-## 或者说, "我应如何学会不再担心并开始爱上Git。"
-
-本文档旨在指导新手以最佳方式获得为QMK做出贡献的丝滑体验。我们将介绍为QMK做出贡献的过程,详细介绍使这项任务更容易的一些方法,然后我们将制造一些问题,来教你如何解决它们。
-
-本文假设了一些内容:
-
-1. 一有个GitHub账户, 并[创建qmk_firmware仓库分叉](getting_started_github.md)到你的帐户.
-2. 你已经[建立你的构建环境](newbs_getting_started.md?id=environment-setup).
-
-
-## 你分叉的主分支: 一直在上传,但不要提交
-
-十分推荐您在QMK开发过程中无论开发是否完成都要保持你的 `master` 分支更新,但是 ***一定不要*** 提交。相反,你应该在一个开发分叉中做出你所有修改并在开发时提交pull request。
-
-减少合并冲突的可能性 &mdash; 两个或多个用户同时编辑文件的同一部分的实例 &mdash; 保持 `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/<your_username>/qmk_firmware.git (fetch)
-origin https://github.com/<your_username>/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 &mdash; 统称为"refs" &mdash; 从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` &mdash; `-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 <conflicted_files>", 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
-<p>For help with any issues, email us at support@webhost.us.</p>
-=======
-<p>Need help? Email support@webhost.us.</p>
->>>>>>> Commit #1
-```
-
- `<<<<<<< HEAD`行标记合并冲突的开始, `>>>>>>> Commit #1` 行标记结束, 冲突选项被 `=======`分隔。`HEAD`那端的部分来自文件的qmk master版本,标记有commit消息的部分来自当前的分支持和提交。
-
-因为Git跟踪 *对文件的更改* 而不是直接跟踪文件的内容,所以如果Git在提交之前找不到文件中的文本,它将不知道如何编辑该文件。重新编辑文件将解决冲突。进行更改,然后保存文件。
-
-```
-<p>Need help? Email support@webhost.us.</p>
-```
-
-现在运行:
-
-```
-git add conflicting_file_1.txt
-git rebase --continue
-```
-
-Git记录对冲突文件的更改,并继续应用来自我们的分支的提交,直到它到达末尾。
diff --git a/docs/zh-cn/newbs_building_firmware.md b/docs/zh-cn/newbs_building_firmware.md
index fc43583c2b..681c7ba8f6 100644
--- a/docs/zh-cn/newbs_building_firmware.md
+++ b/docs/zh-cn/newbs_building_firmware.md
@@ -1,81 +1,68 @@
# 构建第一个固件
-现在您已经建立了构建环境,就可以开始构建自定义固件了。对于本指南的这一部分,我们将在3个程序之间切换——文件管理器、文本编辑器和终端窗口。请保持所有3个程序打开,直到您完成并对键盘固件满意。
+<!---
+ original document: 0.15.12:docs/newbs_building_firmware.md
+ git diff 0.15.12 HEAD -- docs/newbs_building_firmware.md | cat
+-->
-如果您在按照指南第一部分的操作之后关闭并重新打开了终端窗口,请不要忘记输入“cd qmk_firmware”,来使您的终端位于正确的目录。
+现在您已经准备好了构建环境,就可以开始构建自定义固件了。在这节指南中,我们将在3个程序中开展工作——文件管理器、文本编辑器和终端。在做出心满意足的固件前,请不要关闭它们。
+## 新建键映射
-## 导航到您的keymaps文件夹
+也许你会考虑从默认键映射复制一份来开始,如果你遵循编译环境配置指南到了最后,那么使用QMK命令行可以简单地做到:
-首先导航到键盘的 `keymaps` 文件夹.
+ qmk new-keymap
-?> 如果您使用的是MacOS或Windows,可以使用以下命令轻松地打开keymaps文件夹。
+如果你的环境没有那样配置,或者你有多个键盘要做,可以指定键盘名:
-?> macOS:
+ qmk new-keymap -kb <keyboard_name>
- open keyboards/<keyboard_folder>/keymaps
+检查命令行输出,应该类似于:
-?> Windows:
+ Ψ <github_username> keymap directory created in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/<github_username>
- start .\\keyboards\\<keyboard_folder>\\keymaps
+上面就是创建出的新 `keymap.c` 文件的路径。
-## 创建`default` 布局副本
+## 使用趁手的编辑器打开 `keymap.c`
-打开`keymaps`文件夹后,您将需要创建`default`文件夹的副本。我们强烈建议您将文件夹命名为与GitHub用户名相同的名称,但您也可以使用任何您想使用的名称,只要它只包含小写字母、数字和下划线字符。
-
-要自动执行此过程,您还可以选择运行`new_keymap.sh`脚本。
-
-导航到`qmk_firmware/util` 目录然后输入以下命令:
-
-```
-./new_keymap.sh <keyboard path> <username>
-```
-
-例如,一个名字叫ymzcdg的用户要创建1up60hse的布局,他需要输入
-
-```
-./new_keymap.sh 1upkeyboards/1up60hse ymzcdg
-```
-
-## 在你最钟爱的文本编辑器中打开`keymap.c`
-
-打开你的`keymap.c`. 在这个文件中,您可以找到控制键盘行为的结构。 在你的`keymap.c` 的顶部有一些让布局更易读的define和enum。在靠下的位置你会找到一行和下面这句很像的:
+在编辑器中打开 `keymap.c`,可以看到控制键盘所有功能的关键结构。`keymap.c` 文件头部的一些define和enum定义能让代码容易阅读一些,继续往下会找到这么一行:
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-从这一行开始便是层列表。这行下面你会看到包括 `LAYOUT` 或 `KEYMAP`这两个词的几行, 从这些行开始就是层。在这一行下面是组成该特定层的键的列表。
+这行是所有层定义的起点,往下能看到有 `LAYOUT` 的行,都是一个层定义的起始,其下方为该层的组成定义。
-!> 编辑您的keymap文件时,注意不要添加或删除任何逗号。如果这样做,您将阻止您的固件编译,并且您可能不容易找出多余的或缺少的逗号在哪里。
+!> 编辑时请非常留意不要错误增加/删除了逗号分隔符,否则很可能无法编译固件,且很难排查是哪里的逗号不对。
-## 根据您的喜好自定义布局
+## 按照个人喜好设计层级
-如何完成这一步骤完全取决于您。改变一直困扰着你的问题,或者完全重做所有的事情。如果您不需要全部图层,可以删除图层,或者将图层总数增加到32个。查看以下文档,了解可以在此处定义的内容:
+这一步的目标完全取决于你,既可以去修复一个你不爽的问题,也可以完全重写一个新的。你可以删除不需要的层,或是增加层到32个的上限,QMK功能丰富,可以在左边的导航栏中寻找“使用QMK”一节,浏览完整的功能信息,也可以看看这些比较简单的:
-* [键码](keycodes.md)
-* [特性](features.md)
-* [问题与解答](faq.md)
+* [基础键码](zh-cn/keycodes_basic.md)
+* [量子键码](zh-cn/quantum_keycodes.md)
+* [Grave/Escape](zh-cn/feature_grave_esc.md)
+* [鼠标键](zh-cn/feature_mouse_keys.md)
-?> 当你明白布局是怎么工作时,您也要让每次改变尽可能小。一次改变很大在调试时找出问题会十分困难。
+?> 你大概理解了键映射如何工作的话,留心尽量少去做改动,改动越多出了问题越难排查。
-## 构建你的固件
+## 构建固件 :id=build-your-firmware
-完成对布局的更改后,您就要构建固件了。为此,请返回终端窗口并运行build命令:
+对键映射做完修改后,该编译固件了。回到终端中使用编译命令:
- make <my_keyboard>:<my_keymap>
+ qmk compile
-例如,如果您的keymap名为“xyverz”,并且您正在为rev5 planck构建一个keymap,那么您将使用此命令:
+如果没有完整地配置环境,或你有多个目标键盘,可以指定键盘及键映射:
- make planck/rev5:xyverz
+ qmk compile -kb <keyboard> -km <keymap>
-在编译过程中,你将看到屏幕上有很多输出,通知您正在编译哪些文件他应该以与下文类似的输出结束:
+编译完成后,会输出详尽的编译产出文件信息,其末尾应该看起来像这样:
```
-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
+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)
```
-## 刷新你的固件
+## 刷写固件
-请移步 [Flashing Firmware](newbs_flashing.md) 来继续。
+参阅[刷写固件](zh-cn/newbs_flashing.md)以了解如何将固件写入键盘主控。
diff --git a/docs/zh-cn/newbs_building_firmware_configurator.md b/docs/zh-cn/newbs_building_firmware_configurator.md
new file mode 100644
index 0000000000..c4cd114318
--- /dev/null
+++ b/docs/zh-cn/newbs_building_firmware_configurator.md
@@ -0,0 +1,18 @@
+# QMK配置器
+
+<!---
+ original document: 0.15.12:docs/newbs_building_firmware_configurator.md
+ git diff 0.15.12 HEAD -- docs/newbs_building_firmware_configurator.md | cat
+-->
+
+[![QMK配置器截图](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/)
+
+[QMK配置器](https://config.qmk.fm)是一个可用于生成`.hex`和`.bin`格式的QMK固件文件的在线交互页面。
+
+这里有[视频教程](https://www.youtube.com/watch?v=-imgglzDMdY). 很多人给我们反馈该视频包含了足够多的知识可以用来开始编写自己的键盘程序。
+
+QMK配置器在Chrome及Firefox中工作良好。
+
+!> **来自于第三方工具的文件数据无法保证与QMK兼容,如Keyboard Layout Editor(KLE)或kbfirmware,请不要加载或导入这些文件。QMK配置器是一个独立的工具。**
+
+更多信息请参见[QMK配置器: 入门](zh-cn/configurator_step_by_step.md)。
diff --git a/docs/zh-cn/newbs_flashing.md b/docs/zh-cn/newbs_flashing.md
index 05a9eb55ee..9ffb792793 100644
--- a/docs/zh-cn/newbs_flashing.md
+++ b/docs/zh-cn/newbs_flashing.md
@@ -1,307 +1,124 @@
-# 刷新你的键盘
+# 刷写键盘固件
-现在您已经构建了一个自定义固件文件,那么您就需要刷新键盘了。
+<!---
+ original document: 0.15.12:docs/newbs_flashing.md
+ git diff 0.15.12 HEAD -- docs/newbs_flashing.md | cat
+-->
-## 用QMK工具箱刷新键盘
+在自定义的固件文件构建出来后,可以刷写到键盘中了。
-刷新键盘的最简单方法是使用[QMK 工具箱](https://github.com/qmk/qmk_toolbox/releases).
+## 将键盘调至DFU(Bootloader)模式
-但是,QMK工具箱目前仅适用于Windows和MacOS。如果您使用的是Linux(或者只是希望从命令行刷新固件),则必须使用 [方法概述](newbs_flashing.md#flash-your-keyboard-from-the-command-line).
+在你将自定义固件刷写到键盘前,键盘必须处于特有的刷写模式下。此时,键盘会处于不会响应点击等常规操作的状态,并且一定留意不要打断刷写工作,刷写固件过程中不可以把键盘拔下来。
-### 将文件加载到QMK工具箱中
+不同的键盘进入刷写模式的方法都是不同的,如果你的键盘运行的是QMK、TMK或PS2AVRGB(Bootmapper客户端)且没有写明特别的操作说明的话,可以依次尝试以下操作:
-首先打开QMK工具箱应用程序。您将要在访达或资源管理器中找到固件文件。您的键盘固件可能是两种格式之一`.hex`或`.bin`。qmk会尝试将键盘的相应文件复制到“qmk_firmware”根目录中。
+* 按住两边的Shift键,点击Pause
+* 按住两边的Shift键,点击B
+* 拔出键盘,同时按住“空格”键及B键,再插上键盘,等两秒后松开
+* 拔出键盘,按住键盘左上或左下的按键(一般来讲是Escape或左Control),在插上键盘
+* 按重置按键(Reset),一般在PCB背面
+* 在PCB上寻找导出的 `RESET` 和 `GND` 引脚,在插电的情况下短接一下
-?> 如果您在Windows或MacOS上,可以使用以下命令轻松地在资源管理器或访达中打开当前固件文件夹。
+如果上面的方法没有用,且键盘主板上的芯片是 `STM32` 系列,情况要复杂一些。通常在[Discord](https://discord.gg/Uq7gcHh)上寻求帮助是最好的办法,并且很可能需要你提供一些键盘主板的照片 —— 所以如果你能提前准备好,我们沟通起来会快得多。
-?> Windows:
+如果没有遇到什么问题,你会在QMK工具箱的输出信息里找到类似下面的黄色文字的信息:
- start .
-
-?> macOS:
-
- open .
-
-固件文件始终遵循此命名格式:
+```
+*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000)
+```
- <keyboard_name>_<keymap_name>.{bin,hex}
+已进入bootloader状态的设备也可以在设备管理器、系统信息或 `lsusb` 中看到。
-例如,使用 `default` 布局的 `plank/rev5` 将使用以下名字:
+## 使用QMK工具箱刷写固件
- planck_rev5_default.hex
+使用[QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)刷写固件是最简单的方案。
-找到固件文件后,将其拖到QMK工具箱中的“Local file”框中,或单击“Open”并导航到固件文件的存储位置。
+然而该工具箱仅支持Windows及macOS,如果你在使用Linux环境(或是希望用命令行刷写固件),请参阅[在命令行中刷写固件](#使用命令行刷写固件)一节。
-### 将键盘置于DFU(Bootloader)模式
+### 加载固件到QMK工具箱
-要刷新自定义固件,您必须将键盘置于特殊的刷新模式。在此模式下,您将无法键入或使用键盘。在写入固件时,不要拔下键盘插头或以其他方式中断刷新过程,这一点非常重要。
+打开QMK工具箱,在Finder或文件管理器中找到固件文件。键盘固件文件名后缀通常是 `.hex` 或 `.bin`,QMK工具箱会尝试将正确的文件拷贝到qmk根目录 `qmk_firmware` 中。
-不同的键盘有不同的方式进入这种特殊模式。如果您的键盘当前运行的是QMK或TMK,而您没有得到特定的指示,请按顺序尝试以下操作:
+在Windows或macOS上,使用下面的指令可以快速打开当前目录。
-* 按住两个shift键并按 `Pause`
-* 按住两个shift键并按 `B`
-* 拔下键盘插头, 同时按住空格键和 `B` , 插上键盘然后等一会再放开按键
-* 按下PCB底部的 `RESET` 物理键
-* 找到PCB上标记有 `BOOT0` 或 `RESET`的金属点, 在插入PCB的同时短接它们
+<!-- tabs:start -->
-成功后,您将在QMK工具箱中看到类似以下内容的消息:
+#### ** Windows **
```
-*** Clueboard - Clueboard 66% HotSwap disconnected -- 0xC1ED:0x2390
-*** DFU device connected
+start .
```
-### 刷新你的键盘
-
-单击QMK工具箱中的 `Flash` 按钮。您将看到类似以下内容的输出:
+#### ** macOS **
```
-*** 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
+open .
```
-## 使用命令行刷新键盘
-
-首先,您需要知道您的键盘使用的是哪个bootloader。通常是以下四个常见的bootloader。Pro-Micro 和 clones 使用 CATERINA, Teensy 使用 Halfkay, OLKB 键盘使用 QMK-DFU, 其他的atmega32u4芯片使用DFU。
-
-您可以在以下文章中了解更多关于bootloader[刷新指令和Bootloader信息](flashing.md)。
-
-如果您知道正在使用的bootloader是哪种,那么在编译固件时,可以向“make”命令里添加一些额外参数,以自动执行刷新过程。
+<!-- tabs:end -->
-### DFU
+固件文件的文件名格式为:
-对于DFU引导加载程序,当您准备好编译和刷新固件时,打开终端窗口并运行构建命令:
-
- make <my_keyboard>:<my_keymap>:dfu
-
-例如,如果您的布局名为“xyverz”,并且您正在为rev5 planck构建一个布局,那么您可以使用此命令:
-
- make planck/rev5:xyverz:dfu
+```
+<keyboard_name>_<keymap_name>.{bin,hex}
+<键盘名>_<键映射名>.{bin,hex}
+```
-编译完成后,应输出以下内容:
+例如, `planck/rev5` 的 `default` 键映射对应的文件名是:
```
-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
- ```
+planck_rev5_default.hex
+```
-到了这个时候, 构建脚本将每隔5秒查找一次DFU。它将重复以下操作,直到找到设备或将其取消。
+找到固件文件后,将其拖拽至QMK工具箱的"Local file"框,或点击“Open”并定位至固件文件。
- dfu-programmer: no device present.
- Error: Bootloader not found. Trying again in 5s.
+### 刷写到键盘
-一旦出现以上回显,您将需要重置控制器。然后,它应该显示与以下类似的输出:
+点击QMK工具箱的`Flash`,将看到如下输出信息:
```
+*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000)
*** Attempting to flash, please don't remove device
->>> dfu-programmer atmega32u4 erase --force
+>>> dfu-programmer.exe 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...
+>>> 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
- 0x5600 bytes written into 0x7000 bytes memory (76.79%).
->>> dfu-programmer atmega32u4 reset
-```
-
-如果您对此有任何问题,您可能需要这样做:
-
- sudo make <my_keyboard>:<my_keymap>: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 <my_keyboard>:<my_keymap>: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.
+ 0x3F80 bytes written into 0x7000 bytes memory (56.70%).
+>>> dfu-programmer.exe atmega32u4 reset
+
+*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000)
```
-如果您对此有任何问题,您可能需要这样做:
-
- sudo make <my_keyboard>:<my_keymap>:avrdude
-
-此外,如果要刷新多个板,请使用以下命令:
+## 使用命令行刷写固件
- make <keyboard>:<keymap>:avrdude-loop
+现在已经没有以前那样繁琐了,在编译固件后需要刷写时,打开终端输入如下刷写指令:
-当你完成了刷新后,你需要按下ctrl+c或者其他正确的按键来让你的操作系统终止循环。
+ qmk flash
+如果未通过命令行工具配置过键盘/键映射名,或有多个目标键盘,可以指定目标键盘和键映射:
-## HalfKay
+ qmk flash -kb <键盘名> -km <键映射名>
-对于PJRC设备(Teensy),当您准备好编译和刷新固件时,打开终端窗口并运行构建命令:
+QMK将核查键盘配置,并尝试使用合适的bootloader进行刷写。也就是说,你不用关注应该使用什么bootloader,这些重活儿让qmk指令去承担就好。
- make <my_keyboard>:<my_keymap>:teensy
+但是,先决条件是键盘配置中已经设置了bootloader,如果未配置,或你的键盘板子不支持配置的刷写方式,你会看到这些错误信息:
-比如, 如果你的布局叫做"xyverz"你想创建Ergodox or Ergodox EZ的布局,你要使用以下命令:
+ WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time.
- 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
-```
+此时,只能退回到需要指定bootloader的方法,具体参见[刷写固件](zh-cn/flashing.md)指引。
-## STM32 (ARM)
-
-对于大多数ARM板(包括Proton C、Planck Rev 6和Preonic Rev 3),当您准备好编译和刷新固件时,打开终端窗口并运行构建命令:
-
- make <my_keyboard>:<my_keymap>: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
-```
+## 上手试试键盘吧!
-## 试一试吧!
+恭喜你,你的自定义固件成功刷写到键盘中了,快去试试吧!
-恭喜您! 您的自定义固件已经刷写到您的键盘
+运气不差的话一切都会是正常工作的,如果不幸遇到了些问题,有一些参考方案可以帮助你排查问题原因。
+键盘测试就简单直接了,依次按一下各按键,检查它是不是发送了正确的输入。可以使用[QMK配置器](https://config.qmk.fm/#/test/)中的测试模式进行测试,即便你的键盘并不运行QMK。
-试一试,确保一切按你想的方式进行。我们写了[测试和调试](newbs_testing_debugging.md)来完善新手引导。 因此,请前往那里了解如何排除自定义功能的故障。
+还是不行吗?参阅一下FAQ或[通过Discord和我们聊聊](https://discord.gg/Uq7gcHh)吧。
diff --git a/docs/zh-cn/newbs_getting_started.md b/docs/zh-cn/newbs_getting_started.md
index 596ab78f7f..7ca9871aa7 100644
--- a/docs/zh-cn/newbs_getting_started.md
+++ b/docs/zh-cn/newbs_getting_started.md
@@ -1,93 +1,183 @@
-# 介绍
+# 配置环境
-你的电脑键盘里面包含一个处理器, 这个处理器和你电脑里面的不太一样。这个处理器负责运行一些特殊的软件,这些软件可以监测按钮按下并将按钮处于按下还是释放状态的数据发送出去。QMK就是这样一种软件,即监测按钮被按下并发送这样的信息到作为主机的计算机上。当你创建了你的布局, 你也就创建了你的键盘运行的的可执行程序。
+<!---
+ original document: 0.15.12:docs/newbs_getting_started.md
+ git diff 0.15.12 HEAD -- docs/newbs_getting_started.md | cat
+-->
-QMK试图通过使简单的事情变得更简单,使使不可能成为可能来把大量的权力交给你。你不需要懂如何通过程序创建强大的布局——你只需要遵循简单的语法规则。
+构建键映射前,有一些必须安装配置的构建工具,但无论你要编译多少个固件,这一步只需要做一次。
-# 新手上路
+## 1. 必备工具
-在你能创建布局前,你要安装一些软件来建立你的开发环境。无论你想编译多少固件,这个操作都只需要进行一次。
+首先需要确保一些基本的软件配备。
-如果您更喜欢图形化界面, 请考虑使用在线工具[QMK配置器](https://config.qmk.fm)。 请参考 [使用在线GUI构建您的第一个固件](newbs_building_firmware_configurator.md)。
+* [文本编辑器](zh-cn/newbs_learn_more_resources.md#text-editor-resources)
+ * 你需要至少一个能编辑常规文本的软件。系统自带的编辑器通常不会如实保存(会做一些额外的处理,如回车),所以选择编辑器时需要留意。
+* [QMK工具箱(可选)](https://github.com/qmk/qmk_toolbox)
+ * 在Windows及macOS上可用的图形程序,用于编辑及调试你的键盘
+?> 如果你没有Linux/Unix命令行使用经验,有些基本概念需要先学习一下。[这些资料](zh-cn/newbs_learn_more_resources.md#command-line-resources)是个使用QMK很好的参考。
-## 下载软件
+## 2. 准备构建环境 :id=set-up-your-environment
-### 文本编辑器
+我们已经尽力让QMK易于配置了,你只要准备好Linux或Unix环境,剩余的交给QMK来安装。
-你需要一个可以编辑 **纯文本** 文件的程序。在Windows上你可以用Notepad, 在Linux上使用gedit,这两个都是简单又实用的文本编辑工具。 在macOS上, 请小心使用 “文本编辑” 这个默认软件: 如果你不明确的选择_格式_菜单中的 _制作纯文本_ 的话文本将不会被保存为纯文本。
+<!-- tabs:start -->
-你也可以下载并安装一个专用编辑器 [Sublime Text](https://www.sublimetext.com/) 或 [VS Code](https://code.visualstudio.com/)。 这大概是跨平台的最好方法了, 这些编辑器是专门为了编辑代码设计的。
+### ** Windows **
-?>搞不清用哪种编辑器? Laurence Bradford 写了篇关于编辑器选择的文章 [a great introduction](https://learntocodewith.me/programming/basics/text-editors/)。
+QMK有维护一套基于MSYS2的软件包,所有命令行程序和依赖都是齐备的。通过 `QMK MSYS` 快捷命令可以快速启动开发环境。
-### QMK 工具箱
+#### 依赖项
-QMK 工具箱 是一种可选的Windows和macOS下的图形化工具,它可以对你的定制键盘进行编程和调试。你可能会发现它就是你能简单的刷新你的键盘固件并查看调试信息的稀世珍宝。
+需安装[QMK MSYS](https://msys.qmk.fm/),最新版在[这里](https://github.com/qmk/qmk_distro_msys/releases/latest)。
-[在这里下载最新发布版本](https://github.com/qmk/qmk_toolbox/releases/latest)
+此外,如果想自行安装MSYS2环境,下面给出了具体的步骤。
-* Windows用户: `qmk_toolbox.exe` (绿色版) 或 `qmk_toolbox_install.exe` (安装版)
-* macOS用户: `QMK.Toolbox.app.zip` (绿色版) or `QMK.Toolbox.pkg` (安装版)
+<details>
+ <summary>自行安装</summary>
-## 建立你的环境
+?> 若决定使用 `QMK MSYS`,请跳过此节.
-我们为了使QMK环境变得更容易建立已竭尽所能。你只需要准备Linux 或 Unix 环境, 然后让QMK安装剩余部分。
+#### 依赖项
-?> 如果你从未使用过Linux/Unix的命令行,有一些你需要学习的基础概念和命令,以下资料将教会您使用QMK环境的必要能力:<br>
-[必会Linux命令](https://www.guru99.com/must-know-linux-commands.html)<br>
-[一些基本的Unix命令](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html)
+遵循 https://www.msys2.org 上的指引,安装MSYS2、Git和Python。
-### Windows
+在MSYS2安装完毕后,关闭所有的MSYS终端,启动新的MinGW 64-bit终端。
-你需要安装MSYS2和Git.
+!> **注意:** MinGW 64-bit 终端*不同于*安装包最后打开的MSYS终端,窗口标题应当是紫色的"MINGW64"而不是"MSYS"。具体的差异可以[参考这里](https://www.msys2.org/wiki/MSYS2-introduction/#subsystems)。
-* 按照以下安装说明进行操作[MSYS2 主页](https://www.msys2.org)。
-* 关闭所有打开的MSYS2终端并打开新的MSYS2 MinGW 64-bit终端。
-* 使用以下命令安装Git: `pacman -S git`。
+执行如下命令:
-### macOS
+ pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip
-你需要安装Homebrew。按照以下说明进行操作 [Homebrew 主页](https://brew.sh)。
+#### 安装
-在Homebrew安装完成后, 继续 _同步QMK工程_. 这一步你将会通过运行一个脚本安装其他包。
+安装QMK命令行程序:
-### Linux
+ python3 -m pip install qmk
-你将需要安装Git.你很有可能已经安装,但若你尚未安装,可以使用以下命令进行安装:
+</details>
-* Debian / Ubuntu / Devuan: `apt-get install git`
-* Fedora / Red Hat / CentOS: `yum install git`
-* Arch: `pacman -S git`
+### ** macOS **
-?> 无论你使用哪种平台,Docker都可以是你的选择[点这里进一步了解](getting_started_build_tools.md#docker)
+QMK维护了一套Homebrew tap和formula以用于自动安装命令行程序及依赖项。
-## 同步QMK工程
+#### 依赖项
-当你建立Linux/Unix环境后,你就已经可以下载QMK了.下载时我们可以用Git来 "clone" QMK仓库. 打开一个终端或MSYS2 MinGW 窗口,在阅读剩余的指南时请保持窗口打开。在窗口里面运行以下两句命令:
+须先安装Homebrew,可以参考 https://brew.sh
-```shell
-git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git
-cd qmk_firmware
-```
+#### 安装
+
+安装QMK命令行程序:
+
+ brew install qmk/qmk/qmk
+
+### ** Linux/WSL **
+
+?> **WSL用户注意**: 默认情况下,QMK仓库会被clone到home目录下,如果想指定其它目录,务必留意要放在WSL文件系统中(即,非 `/mnt` 目录下),否则文件读写会[非常慢](https://github.com/microsoft/WSL/issues/4197).
+
+#### 依赖项
+
+须安装Git及Python,通常你肯定已经有了,如果确实没有,请使用下面的方法尝试安装:
+
+* Debian / Ubuntu / Devuan: `sudo apt install -y git python3-pip`
+* Fedora / Red Hat / CentOS: `sudo yum -y install git python3-pip`
+* Arch / Manjaro: `sudo pacman --needed --noconfirm -S git python-pip libffi`
+* Void: `sudo xbps-install -y git python3-pip`
+* Solus: `sudo eopkg -y install git python3`
+* Sabayon: `sudo equo install dev-vcs/git dev-python/pip`
+* Gentoo: `sudo emerge dev-vcs/git dev-python/pip`
+
+#### 安装
+
+安装QMK命令行程序:
+
+ python3 -m pip install --user qmk
+
+#### 社区提供的包
+
+有一些社区成员提供的包,可能版本会有落后或是功能不全的问题,如果你遇到了什么问题,请联系维护它的社区成员。
+
+Arch系环境下可以使用官方源安装命令行程序(在写这份文档时,有些依赖项被标记为可选的,其实不是):
+
+ sudo pacman -S qmk
+
+也可以尝试AUR的 `qmk-git`:
+
+ yay -S qmk-git
+
+### ** FreeBSD **
+
+#### 安装
+
+使用FreeBSD包安装QMK命令行程序:
+
+ pkg install -g "py*-qmk"
+
+请遵循安装后输出的指引操作进行配置(使用 `pkg info -Dg "py*-qmk"` 可以显示这份指引)。
+
+<!-- tabs:end -->
+
+## 3. 执行QMK配置 :id=set-up-qmk
+*译注:由于setup过程中需要从github clone依赖项,请先确保科学上网*
+
+<!-- tabs:start -->
-?> 如果您已经知道[如何使用GitHub](getting_started_github.md), 我们推荐您创建您自己的分支并克隆。 如果您不知道这是什么, 您完全可以忽略这句无关紧要的话。
+### ** Windows **
-QMK附带一个脚本,可帮助您设置剩余的所需内容.您可以通过输入此命令来运行它:
+安装QMK后,执行:
- util/qmk_install.sh
+ qmk setup
-## 测试你的开发环境
+通常所有的询问回复 `y` 就行了。
-现在你的QMK环境已经建立完毕, 你可以为你的键盘创建固件了。开始试着创建键盘的默认固件吧。 你需要使用以下格式的命令创建固件:
+### ** macOS **
- make <keyboard>:default
+安装QMK后,执行:
-比如, 制作一个Clueboard 66%的固件,需要用:
+ qmk setup
- make clueboard/66/rev3:default
+通常所有的询问回复 `y` 就行了。
-当完成后你要看到一些回显,尾部如下:
+### ** Linux/WSL **
+
+安装QMK后,执行:
+
+ qmk setup
+
+通常所有的询问回复 `y` 就行了。
+
+?>**Debian及Ubuntu系环境须留意**:
+也许你会遇到 `bash: qmk: command not found` 错误,主要是因为Debian上的Bash 4.4版本引入的一个[bug](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155),`$HOME/.local/bin` 被从PATH环境变量中删除了,后续版本中这个问题已被修复。
+然而Ubuntu很挫地再次引入了这个bug[且没有修复](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562)。
+不过修复也很容易,在当前账户中执行:`echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc`
+
+### ** FreeBSD **
+
+安装QMK后,执行:
+
+ qmk setup
+
+通常所有的询问回复 `y` 就行了。
+
+<!-- tabs:end -->
+
+?> QMK的home目录可以在安装时通过 `qmk setup -H <path>` 来指定,安装后也可以通过[命令行程序来配置](zh-cn/cli_configuration.md?id=single-key-example)`user.qmk_home`变量,可以通过 `qmk setup --help` 查看所有可用配置。
+
+?> 若你熟悉GitHub,[推荐阅读这份指引](zh-cn/getting_started_github.md)通过 `qmk setup <github_username>/qmk_firmware` 来clone你自己的fork。如果你看不懂这一段啥意思,忽略就是了。
+
+## 4. 测试你的构建环境
+
+QMK构建环境搭建完成,可以尝试构建一个键盘固件。使用以下指令格式,先试试编译默认提供的键映射:
+
+ qmk compile -kb <keyboard> -km default
+
+例如,要构建一个Clueboard 66%,就这样执行:
+
+ qmk compile -kb clueboard/66/rev3 -km default
+
+你应当能看到像这样的输出信息:
```
Linking: .build/clueboard_66_rev3_default.elf [OK]
@@ -97,6 +187,22 @@ Checking file size of clueboard_66_rev3_default.hex
* The firmware size is fine - 26356/28672 (2316 bytes free)
```
-# 创建你的布局
+## 5. 配置你的构建环境 (可选的)
+
+通过对默认配置的简单调整,QMK用起来会更有趣一些,我们来试试!
+
+大部分QMK新手手头只有一把键盘,可以通过 `qmk config` 命令将它设置为默认键盘,例如你想将 `clueboard/66/rev4` 设置为默认,可以这样:
+
+ qmk config user.keyboard=clueboard/66/rev4
+
+也可以调整默认的键映射名称。社区上大家常用自己的GitHub用户名,这也是我们推荐的做法。
+
+ qmk config user.keymap=<github_username>
+
+完成后,这些配置就不用管了,编译键盘固件就可以直接这样执行:
+
+ qmk compile
+
+# 制作你自己的键映射
-现在你可以创建属于你自己的布局了! 请移步 [构建你的第一个固件](newbs_building_firmware.md)来继续。
+万事俱备啦!请继续阅读[构建第一个固件](zh-cn/newbs_building_firmware.md).
diff --git a/docs/zh-cn/newbs_learn_more_resources.md b/docs/zh-cn/newbs_learn_more_resources.md
index ccb4fa326c..20fed1f358 100644
--- a/docs/zh-cn/newbs_learn_more_resources.md
+++ b/docs/zh-cn/newbs_learn_more_resources.md
@@ -1,15 +1,35 @@
# 学习资源
-这些资源旨在让QMK社区的新成员更了解新成员文档中提供的信息。
+<!---
+ original document: 0.15.12:docs/newbs_learn_more_resources.md
+ git diff 0.15.12 HEAD -- docs/newbs_learn_more_resources.md | cat
+-->
-Git 资源:
+这些资源旨在让QMK社区的新成员更了解新手教程中的基础知识。
-* [很好的通用教程](https://www.codecademy.com/learn/learn-git)
-* [从例子中学习Git游戏](https://learngitbranching.js.org/)
-* [了解有关GitHub的更多信息的Git资源](getting_started_github.md)
-* [专门针对QMK的Git资源](contributing.md)
+*译注:以下资料超出了QMK核心概念范畴,恕不另行翻译*
+### QMK参考资料
-命令行资源:
+* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 一个站在新人视角,探讨如何使用QMK固件的个人博客。
-* [超棒的命令行通用教程](https://www.codecademy.com/learn/learn-the-command-line)
+### 命令行操作参考资料 :id=command-line-resources
+
+* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line)
+* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)<br>
+* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html)
+
+### 文本编辑器相关参考资料 :id=text-editor-resources
+
+对文本编辑器有选择困难?
+* [a great introduction to the subject](https://learntocodewith.me/programming/basics/text-editors/)
+
+更适用于编程的文本编辑器:
+* [Sublime Text](https://www.sublimetext.com/)
+* [VS Code](https://code.visualstudio.com/)
+
+### 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/)
diff --git a/docs/zh-cn/newbs_testing_debugging.md b/docs/zh-cn/newbs_testing_debugging.md
index d88d9b6f2d..0016d3b816 100644
--- a/docs/zh-cn/newbs_testing_debugging.md
+++ b/docs/zh-cn/newbs_testing_debugging.md
@@ -1,46 +1,14 @@
# 测试和调试
-使用自定义固件刷新键盘后,您就可以测试它了。如果您幸运,一切都会完美运行,但如果没有,这份文件将帮助您找出问题所在。
-
+<!---
+ original document: 0.15.12:docs/newbs_testing_debugging.md
+ git diff 0.15.12 HEAD -- docs/newbs_testing_debugging.md | cat
+-->
## 测试
-测试键盘通常非常简单。按下每一个键并确保它发送的是您期望的键。甚至有一些程序可以帮助您确保没有任何键失效。
-
-注意:这些程序不是由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](https://www.keyboardtester.com) (网页版)
-* [Keyboard Checker](https://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`:
+[已移到这里](zh-cn/faq_misc.md#testing)
-```c
-#include "print.h"
-```
+## 调试 :id=debugging
-之后,您可以使用一些不同的打印功能:
+[已移到这里](zh-cn/faq_debug.md#debugging)
-* `print("string")`: 打印简单字符串.
-* `uprintf("%s string", var)`: 打印格式化字符串
-* `dprint("string")`: 仅在调试模式使能时打印简单字符串
-* `dprintf("%s string", var)`: 仅在调试模式使能时打印格式化字符串
diff --git a/docs/zh-cn/reference_configurator_support.md b/docs/zh-cn/reference_configurator_support.md
new file mode 100644
index 0000000000..aa174ceedb
--- /dev/null
+++ b/docs/zh-cn/reference_configurator_support.md
@@ -0,0 +1,200 @@
+# 在QMK配置器中支持您的键盘
+
+<!---
+ original document: 0.15.12:docs/reference_configurator_support.md
+ git diff 0.15.12 HEAD -- docs/reference_configurator_support.md | cat
+-->
+
+本章节详述了如何在[QMK配置器](https://config.qmk.fm/)中对键盘进行支持。
+
+
+## 配置器如何理解键盘
+
+若要了解配置器如何理解键盘,须先理解配列的宏定义。这里有一份练习,假设这里有一个17键的小键盘PCB方案,就叫做 `numpad`。
+
+```
+|---------------|
+|NLk| / | * | - |
+|---+---+---+---|
+|7 |8 |9 | + |
+|---+---+---| |
+|4 |5 |6 | |
+|---+---+---+---|
+|1 |2 |3 |Ent|
+|-------+---| |
+|0 | . | |
+|---------------|
+```
+
+?> 配列宏定义的更多资料,参见[理解QMK:矩阵扫描](zh-cn/understanding_qmk.md?id=matrix-scanning)及[理解QMK:矩阵到物理配列的映射](zh-cn/understanding_qmk.md?id=matrix-to-physical-layout-map)。
+
+配置器的API会从 `qmk_firmware/keyboards/<keyboard>/<keyboard>.h` 中读取键盘定义的 `.h` 文件。在上面的小键盘示例中,对应文件应为 `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 } \
+}
+```
+
+!> 注意这里的使用模式与键映射中的宏完全不同,后者几乎都在用 `XXXXXXX`(7个大写X)替代 `KC_NO`,用 `_______`(7个下划线)替代 `KC_TRNS`。
+
+!> 为避免混淆,推荐使用 `KC_NO`。
+
+配列宏定义描述该键盘有17个按键,分布在五行四列。我们将这些开关命名为 `k<行号><列号>`,从0计起。命名成什么不太重要,但须确保负责从键映射中接收键码的上半段,与描述矩阵中按键位置的下半段定义匹配一致。
+
+为了能够重现键盘的物理组成样式,须构建并提供一份用于描述按键物理位置和尺寸与开关矩阵绑定关系的JSON文件,以告知配置器程序这些信息。
+
+## 构建JSON文件
+
+构建该JSON描述文件最简便的办法是使用[Keyboard Layout Editor](https://www.keyboard-layout-editor.com/) ("KLE"), 从中获取的原始数据(Raw Data)可以经QMK工具转换为配置器可用的JSON格式数据。由于KLE默认打开显示的是一个小键盘配列,请移除新手引导部分,从剩余部分开始使用。
+
+在配列编辑完毕后,从KLE的原始数据(Raw Data tab)页中拷贝类似如下的内容:
+
+```
+["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转换工具](https://qmk.fm/converter/)页面并粘贴到输入框,点击转换按钮。稍后输出框中即可看到所需的JSON数据。将输出数据拷贝到文本文档中,并命名为 `info.json`,保存到 `numpad.h` 所在目录。
+
+可以通过 `keyboard_name` 元素来指定键盘名称。这里为了演示,会将每个按键独立分行,以更方便于阅读,这不影响配置器的功能。
+
+```json
+{
+ "keyboard_name": "Numpad",
+ "url": "",
+ "maintainer": "qmk",
+ "tags": {
+ "form_factor": "numpad"
+ },
+ "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` 对象,其下每个JSON对象描述了各物理按键,格式如下:
+
+```
+ 按键名,不会在配置器中展现。
+ |
+ | 按键的X坐标,从键盘左侧开始数。
+ | |
+ | |
+ | | 按键的Y坐标,从键盘上侧(后视角)开始数。
+ | | |
+ ↓ ↓ ↓
+{"label":"Num Lock", "x":0, "y":0},
+```
+
+部分对象包含 `"w"` 和 `"h"` 字段,用以描述按键的宽高值。
+
+?> 关于 `info.json` 文件的详细信息,参见[`info.json` 文件格式](zh-cn/reference_info_json.md)。
+
+
+## 配置器如何配置按键
+
+配置器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}
+
+当用户在配置器中选中左上角的按键,并赋予数字区锁定键(NumLock)时,配置器会将 `KC_NLCK` 作为第一个按键进行键映射文件的构建工作,其它按键逻辑类似。其中 `label` 键值未被用到,其用于用户在调试 `info.json` 文件时,可以参考辨认出各按键。
+
+
+## 问题及副作用
+
+目前配置器还不支持按键偏转及类似ISO回车键这种非矩形按键。另外,对于纵向上偏离其行的按键 &mdash; 特别是像[TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/)这种1800配列的键盘中的方向键 &mdash; 如果 `info.json` 文件的贡献者没有做出修正,KLE转JSON数据工具将会不知如何处理。
+
+### 解决方案
+
+#### 非矩阵形状的按键
+
+针对ISO回车键的情况,QMK会将其定制化显示成一个矩形键,宽1.25u高2u,按键矩阵的右边与字母区的右边对齐。
+
+![](https://i.imgur.com/JKngtTw.png)
+*一款60% ISO配列的键盘, 在QMK配置器中的渲染样式。*
+
+#### 纵向偏移的按键
+
+对于纵向偏移的按键,将其视作未偏移的样子放入KLE,最后在转换后的JSON文件中,按需编辑其Y偏移值。
+
+![](https://i.imgur.com/fmDvDzR.png)
+*一款1800配列键盘在KLE中的渲染样式,方向键未进行纵向偏移移动。*
+
+![](https://i.imgur.com/8beYMBR.png)
+*这份Unix差异文件,展示了我们需要在JSON文件中进行的纵向偏移改动。*
diff --git a/docs/zh-cn/reference_glossary.md b/docs/zh-cn/reference_glossary.md
index 06d3632505..e1dfccddd2 100644
--- a/docs/zh-cn/reference_glossary.md
+++ b/docs/zh-cn/reference_glossary.md
@@ -1,5 +1,10 @@
# QMK术语表
+<!---
+ original document: 0.15.12:docs/reference_glossary.md
+ git diff 0.15.12 HEAD -- docs/reference_glossary.md | cat
+-->
+
## ARM
多家公司生产的32位单片机系列,例如Atmel, Cypress, Kinetis, NXP, ST, 和 TI等公司。
@@ -7,16 +12,16 @@
[Atmel](https://www.microchip.com/)公司的单片机系列。 AVR是TMK的初始支持平台。
## AZERTY
-Français (法国)标准键盘布局。用键盘的前六个字母命名。
+Français (法语)标准键盘布局。用键盘的前六个字母命名。
## Backlight(背光)
-键盘上照明的通称。背光通常是一组LED灯,通过键帽或者按轴发光,但也不总是这样。
+键盘上照明的通称。背光通常是一组LED灯,穿过键帽或者轴体发光,但也不总是这样。
## Bluetooth(蓝牙)
-一种短距离点对点无线协议。许多多无线键盘使用此协议。
+一种短距离点对点无线传输协议。许多无线键盘使用此协议。
## Bootloader(引导加载程序)
-一种写到你单片机的保护区的特殊的程序,该程序可以使单片机升级自己的固件,通常是通过USB来升级。
+一种写到你单片机保护区的特殊程序,该程序可以使单片机升级自己的固件,通常是通过USB来升级。
## Bootmagic(热改键)
允许各种键盘行为动态变化的功能,如交换或禁用常用键。
@@ -36,12 +41,12 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
## Dynamic Macro(动态宏)
一种记录在键盘上的宏,当键盘拔出或计算机重新启动时,宏将丢失。
-* [动态宏文档](feature_dynamic_macros.md)
+* [动态宏文档](zh-cn/feature_dynamic_macros.md)
## Eclipse
是一种受C语言开发者追捧的集成开发环境(IDE)。
-* [Eclipse安装说明](eclipse.md)
+* [Eclipse安装说明](zh-cn/other_eclipse.md)
## Firmware(固件)
用来控制单片机的软件。
@@ -52,14 +57,14 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
## GitHub
负责大多数QMK项目的网站。它是Git、问题跟踪和其他帮助我们运行qmk的功能的集成平台。
-## ISP(在系统编程)
-在系统编程(In-system programming), 使用外部硬件和JTAG管脚对AVR芯片进行编程的一种方法。
+## 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).
+表示特定键的2字节数据。`0x00`-`0xFF`用于[基本键码](zh-cn/keycodes_basic.md)而`0x100`-`0xFFFF`用于[量子键码](zh-cn/quantum_keycodes.md).
## Key Down
一个键按下尚未抬起时触发的事件。
@@ -71,12 +76,12 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
映射到物理键盘布局的一组键码,在按键和按键释放时进行处理。有时翻译为布局,意为软件上表示的布局,即映射。
## Layer(层)
-为了让一个键实现多个功能的抽象结构。最高活动层有限。
+为了让一个键实现多个功能的抽象结构。可用层数有上限。
## Leader Key(前导键、设置菜单键)
本功能允许您点击前导键,然后按顺序按1-3个键子来激活按键或其他量子功能。
-* [前导键文档](feature_leader_key.md)
+* [前导键文档](zh-cn/feature_leader_key.md)
## LED
发光二极管,键盘上最常用的指示灯装置。
@@ -90,18 +95,18 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
## Macro(宏)
本功能可以在敲击单个键后发送多个按键事件(hid报告)。
-* [宏文档](feature_macros.md)
+* [宏文档](zh-cn/feature_macros.md)
## MCU(单片机、微控制单元)
微控制单元,键盘的处理器。
-## Modifier(修改键、修饰键、功能键)
+## Modifier(修饰键、修改键、功能键)
按住该键将会改变其他键的功能,修饰键包括 Ctrl, Alt, 和 Shift。
## Mousekeys(鼠标键)
本功能在您敲击键盘时会控制鼠标光标。
-* [鼠标键文档](feature_mouse_keys.md)
+* [鼠标键文档](zh-cn/feature_mouse_keys.md)
## N-Key Rollover (NKRO、全键无冲)
一种术语,适用于能够同时报告任意数量按键的键盘。
@@ -128,17 +133,17 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
HID报告中的一个1字节的数字,表示一个键子。这些数字在下列文档中[HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf)该文档发布于[USB-IF](https://www.usb.org/)。
## Space Cadet键盘的shift键
-一种特使的shift设置,能让你通过敲击左或右shift一次或多次键入不同的括号。
+一种特殊的shift设置,能让你通过敲击左或右shift一次或多次键入不同的括号。
-* [Space Cadet键盘文档](feature_space_cadet.md)
+* [Space Cadet键盘文档](zh-cn/feature_space_cadet.md)
## Tap(敲击、单击)
-按下并释放一个键。在某些情况下您需要区分键按下和键抬起,但是单击把两个事件都包括了。
+按下并抬起一个键。在某些情况下您需要区分键按下和键抬起,但是单击把两个事件都包括了。
## Tap Dance(多击键)
本功能允许向同一个键子分配多个键码,并根据按键次数区分。
-* [多击键文档](feature_tap_dance.md)
+* [多击键文档](zh-cn/feature_tap_dance.md)
## Teensy
一种低成本AVR开发板<!--译者吐槽:我怎么感觉成本不低。好吧,我穷。 -->,通常用于手工连线键盘。这个teensy是有点小贵但是halfkay bootloader会让它刷写十分简单,所以也很常用。
@@ -147,21 +152,47 @@ HID报告中的一个1字节的数字,表示一个键子。这些数字在下
用于照亮电路板底面的LED的总称。这些LED通常从印刷电路板的底部向键盘所在的表面发光。
## Unicode
-在较大的计算机世界中,Unicode是一组编码方案,用于表示任何语言中的字符。 与qmk相关的是,它意味着使用各种操作系统方案来发送Unicode代码点,而不是扫描码。
+在广阔的计算机世界中,Unicode是一组编码方案,用于表示任何语言中的字符。 与qmk相关的是,它意味着使用各种操作系统方案来发送Unicode码点,而不是扫描码。
-* [Unicode文档](feature_unicode.md)
+* [Unicode文档](zh-cn/feature_unicode.md)
## Unit Testing(单元测试)
-针对qmk的自动运行测试框架。单元测试帮助我们确信我们的更改不会破坏任何东西。
+针对qmk的自动测试框架。单元测试帮助我们确信我们的更改不会破坏任何东西。
-* [单元测试文档](unit_testing.md)
+* [单元测试文档](zh-cn/unit_testing.md)
## USB
通用串行总线,键盘最常见的有线接口。
-## USB 主机 (或简易主机)
-USB诸暨市你的电脑,或者你的键盘所插的任何设备。
+## USB 主机 (简称主机)
+USB主机就是你的电脑,或者你的键盘所插的任何设备。
# 并没有找到你想找到的术语?
-[建立一个issue](https://github.com/qmk/qmk_firmware/issues) ,想好你的问题,或许你所问的术语就会添加到这里。创建一个PR帮我们添加需要添加的术语当然坠吼了:)
+[新建一个issue](https://github.com/qmk/qmk_firmware/issues) ,想好你的问题,或许你所问的术语就会添加到这里。创建一个PR帮我们添加需要添加的术语当然坠吼了:)
+
+## 中文翻译术语特别说明(terms of Chinese translation):id=terms-of-zh-cn-translate
+!>如果你对QMK文档翻译中的细节不关心,请跳过该节
+
+由于语言及文化差异,QMK英文文档中的部分内容,很难在**保持原句结构**的情况下,完美地翻译为中文,而保持翻译前后的语句结构一致对于开源代码的文档翻译来讲十分重要,这样才能确保不同的文档贡献者不会*夹带私货*,防止不同的翻译风格、不同的翻译水准、不同的理解与润色最终产生糟糕的混合。
+因此,这里会对一些词组的的翻译进行规范化,并希望阅读者及后续文档翻译维护者,维持这种统一的范式。
+
+### keyboard(键盘)及keymap(键映射)
+QMK文档中使用最多的两个术语是keyboard及keymap
+* 键盘:在中文语境下,我们提及键盘,基本是在指物理键盘,而在QMK文档中到处可见的“键盘”一词,多对应的是代码中 `keyboards\` 目录下的键盘定义,其更接近于我们讲的“配列”的概念,主要描述了键盘的大体结构,物理键数量及排列。
+* 键映射:keymap的作用是定义物理键盘到实际输出键值(keycode)的映射关系,也是QMK最重要、涉及最多的概念。QMK很多功能就是为了能够在不改变键盘物理排列/电路组成/芯片程序的情况下,动态地改变物理按键输出的键值。如,通过层切换,将原先的wasd键,切换到可以上下左右的模式,或是一键切换CapsLock和Control,实现这些功能的核心工作就是一套动态的keymap,即键映射逻辑。这里不使用“布局”一词作为keymap的翻译,是因为该词过于宽泛。键映射即便是不好听,至少解释了意思且语境中不容易误解。
+
+### mod-tap
+倾向于不翻译,直接使用原词。因为找不到合适的译法
+
+### dead key
+直译为死键,西语体系下使用的特殊符号,中文中无对应概念。
+
+### flashing(firmware)
+使用“刷写”而非容易迷惑的“刷新”
+
+### option/configuration/setting
+根据上下文灵活考虑。对于组件化配置的概念,如一个功能支持与否,使用“配置”一词;对于客观上一定存在的某项设置值,使用“设置”一词。
+
+### commit/push/pull等Git术语
+倾向于不翻译。这些词语的对应中文词语过于宽泛或词性不明,非常容易混淆上下文。
diff --git a/docs/zh-cn/support.md b/docs/zh-cn/support.md
new file mode 100644
index 0000000000..e636d29c97
--- /dev/null
+++ b/docs/zh-cn/support.md
@@ -0,0 +1,22 @@
+# 寻求帮助
+
+<!---
+ original document: 0.15.12:docs/support.md
+ git diff 0.15.12 HEAD -- docs/support.md | cat
+-->
+
+你可以从很多渠道获取QMK帮助。
+
+在你前往社区进行沟通前,请先阅览我们的社区[行为守则](https://qmk.fm/coc/)
+
+## 实时沟通
+
+在你需要帮助时,最便捷的办法是通过我们的[Discord服务器](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),对于需要深入讨论或需要调试的问题,会方便得多。
diff --git a/docs/zh-cn/syllabus.md b/docs/zh-cn/syllabus.md
new file mode 100644
index 0000000000..d0b861530a
--- /dev/null
+++ b/docs/zh-cn/syllabus.md
@@ -0,0 +1,77 @@
+# QMK大纲
+
+<!---
+ original document: 0.15.12:docs/syllabus.md
+ git diff 0.15.12 HEAD -- docs/syllabus.md | cat
+-->
+
+这一页旨在帮你建立关于QMK的相关基础知识,并提供能引导你成为QMK大师所需的所有概念。
+
+# 基本概念
+
+如果你还没有看其它部分,先阅读这一节吧。在阅读了[介绍](zh-cn/newbs.md)之后,你可以制作、编译、刷写一个简单的键映射了,以下文档可以助你充实各系列的知识。
+
+* **了解如何使用QMK**
+ * [介绍](zh-cn/newbs.md)
+ * [CLI](zh-cn/cli.md)
+ * [GIT](zh-cn/newbs_git_best_practices.md)
+* **了解键映射**
+ * [层](zh-cn/feature_layers.md)
+ * [键码](zh-cn/keycodes.md)
+ * 含所有可用键码,一些会涉及进阶或高级的话题。
+* **配置IDE** - 可选的
+ * [Eclipse](zh-cn/other_eclipse.md)
+ * [VS Code](zh-cn/other_vscode.md)
+
+# 进阶话题
+
+包含窥探QMK主要功能内部原理的话题。你可以不用阅读这些,然而,跳过这些话题的话,去看高级话题的时候会让你很迷惑。
+
+* **各功能的配置**
+ <!-- * Configuration Overview FIXME(skullydazed/anyone): write this document -->
+ * [音频](zh-cn/feature_audio.md)
+ * 灯光
+ * [背光](zh-cn/feature_backlight.md)
+ * [LED矩阵](zh-cn/feature_led_matrix.md)
+ * [RGB灯光](zh-cn/feature_rgblight.md)
+ * [RGB矩阵](zh-cn/feature_rgb_matrix.md)
+ * [点按配置](zh-cn/tap_hold.md)
+ * [充分利用AVR的存储空间](zh-cn/squeezing_avr.md)
+* **深入键映射**
+ * [键映射](zh-cn/keymap.md)
+ * [键码与自定义函数](zh-cn/custom_quantum_functions.md)
+ * 宏
+ * [动态宏](zh-cn/feature_dynamic_macros.md)
+ * [宏](zh-cn/feature_macros.md)
+ * [Tap Dance](zh-cn/feature_tap_dance.md)
+ * [组合键](zh-cn/feature_combo.md)
+ * [用户空间](zh-cn/feature_userspace.md)
+ * [按键重定义](zh-cn/feature_key_overrides.md)
+
+# 高级话题
+
+这些话题需要较多基础知识,使用这些高级功能前,你应该对如何通过 `config.h` 和 `rules.mk` 来配置键盘选项非常熟悉。
+
+* **维护QMK键盘**
+ * [飞线指南](zh-cn/hand_wire.md)
+ * [键盘开发指引](zh-cn/hardware_keyboard_guidelines.md)
+ * [info.json参考资料](zh-cn/reference_info_json.md)
+ * [防抖API](zh-cn/feature_debounce_type.md)
+* **高级功能**
+ * [Unicode](zh-cn/feature_unicode.md)
+ * [API](zh-cn/api_overview.md)
+ * [Bootmagic Lite](zh-cn/feature_bootmagic.md)
+* **硬件相关**
+ * [键盘工作原理](zh-cn/how_keyboards_work.md)
+ * [键盘矩阵原理](zh-cn/how_a_matrix_works.md)
+ * [分体键盘](zh-cn/feature_split_keyboard.md)
+ * [速记](zh-cn/feature_stenography.md)
+ * [光标设备](zh-cn/feature_pointing_device.md)
+* **开发核心知识**
+ * [C编码规范](zh-cn/coding_conventions_c.md)
+ * [兼容的微处理器](zh-cn/compatible_microcontrollers.md)
+ * [自定义矩阵](zh-cn/custom_matrix.md)
+ * [理解QMK](zh-cn/understanding_qmk.md)
+* **CLI开发**
+ * [编码规范](zh-cn/coding_conventions_python.md)
+ * [CLI开发总览](zh-cn/cli_development.md)
diff --git a/docs/zh-cn/translating.md b/docs/zh-cn/translating.md
new file mode 100644
index 0000000000..fa80ffd7f8
--- /dev/null
+++ b/docs/zh-cn/translating.md
@@ -0,0 +1,60 @@
+# 翻译QMK文档
+
+<!---
+ original document: 0.15.12:docs/translating.md
+ git diff 0.15.12 HEAD -- docs/translating.md | cat
+-->
+
+根目录下(`docs/`)的所有文件应当是英语的 - 其它语言应使用 ISO 639-1 中定义的语言编码建立子目录,后跟随一个 `-` 以及必要的国家编码。[常见的语言编码可见这里](https://www.andiamo.co.uk/resources/iso-language-codes/)。如果此目录不存在,可以新建。每个翻译过的文件的文件名,都应保持与英语版本的一致,以确保超链接的退化兼容性。
+
+文件夹下的 `_summary.md` 文件中,有链接向其它文件的地址,在翻译过的名称后,跟随的链接前应添加该语言的目录名:
+
+```markdown
+ * [QMK简介](zh-cn/getting_started_introduction.md)
+```
+
+所有导向其它文档页面的链接也必须有语言目录名前缀,若还指向了页面指定位置(即特定的标题),必须使用标题的英文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编码](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',
+ // ...
+ ],
+ ```
+
+## 预览你的翻译成果
+
+请阅读[文档预览](zh-cn/contributing.md#previewing-the-documentation)来设置文档的本地预览 - 在页面右上角的 "Translations" 菜单中应当可以看到你翻译的语言的入口。
+
+当你觉得一切就绪了,请发起pull request给我们吧!
diff --git a/docs/zh-cn/zh_cn_doc_status.sh b/docs/zh-cn/zh_cn_doc_status.sh
new file mode 100644
index 0000000000..84693e5461
--- /dev/null
+++ b/docs/zh-cn/zh_cn_doc_status.sh
@@ -0,0 +1,35 @@
+#! /bin/sh
+#
+# Script to display Simplified Chinese translation status of documents
+# Copied from the japanese one
+#
+if [ ! -d docs/zh-cn ]; then
+ echo "'docs/zh-cn' not found."
+ echo "do:"
+ echo " cd \$(QMK_TOP)"
+ echo " ./docs/zh-cn/zh-cn_doc_status.sh"
+ exit 1
+fi
+
+en_docs=`cd docs;ls -1 [a-z]*.md`
+zh_cn_docs=`cd docs/zh-cn;ls -1 [a-z]*.md`
+en_count=`echo $en_docs | wc -w`
+zh_cn_count=`echo $zh_cn_docs | wc -w`
+echo "English documents $en_count files."
+echo "Simplified Chinese documents $zh_cn_count files."
+
+echo "Files that have not been translated yet:"
+for docfile in $en_docs
+do
+ if [ ! -f docs/zh-cn/$docfile ]; then
+ wc docs/$docfile
+ fi
+done | sort
+echo "Files that have not been updated yet:"
+grep --no-filename "^[ ]*git diff" docs/zh-cn/*.md | while read cmd
+do
+ cline=`echo $cmd | sh | wc -l`
+ if [ $cline -gt 0 ]; then
+ echo "$cline $cmd"
+ fi
+done | sort