aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/icu.c
blob: c73ea5106fec340e09c8e66f0ad5f4af581037d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
                 2011 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file    icu.c
 * @brief   ICU Driver code.
 *
 * @addtogroup ICU
 * @{
 */

#include "ch.h"
#include "hal.h"

#if HAL_USE_ICU || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver local definitions.                                                 */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported variables.                                                */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local variables.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local functions.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported functions.                                                */
/*===========================================================================*/

/**
 * @brief   ICU Driver initialization.
 * @note    This function is implicitly invoked by @p halInit(), there is
 *          no need to explicitly initialize the driver.
 *
 * @init
 */
void icuInit(void) {

  icu_lld_init();
}

/**
 * @brief   Initializes the standard part of a @p ICUDriver structure.
 *
 * @param[out] icup     pointer to the @p ICUDriver object
 *
 * @init
 */
void icuObjectInit(ICUDriver *icup) {

  icup->state  = ICU_STOP;
  icup->config = NULL;
}

/**
 * @brief   Configures and activates the ICU peripheral.
 *
 * @param[in] icup      pointer to the @p ICUDriver object
 * @param[in] config    pointer to the @p ICUConfig object
 *
 * @api
 */
void icuStart(ICUDriver *icup, const ICUConfig *config) {

  chDbgCheck((icup != NULL) && (config != NULL), "icuStart");

  chSysLock();
  chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
              "icuStart(), #1", "invalid state");
  icup->config = config;
  icu_lld_start(icup);
  icup->state = ICU_READY;
  chSysUnlock();
}

/**
 * @brief   Deactivates the ICU peripheral.
 *
 * @param[in] icup      pointer to the @p ICUDriver object
 *
 * @api
 */
void icuStop(ICUDriver *icup) {

  chDbgCheck(icup != NULL, "icuStop");

  chSysLock();
  chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
              "icuStop(), #1", "invalid state");
  icu_lld_stop(icup);
  icup->state = ICU_STOP;
  chSysUnlock();
}

/**
 * @brief   Enables the input capture.
 *
 * @param[in] icup      pointer to the @p ICUDriver object
 *
 * @api
 */
void icuEnable(ICUDriver *icup) {

  chDbgCheck(icup != NULL, "icuEnable");

  chSysLock();
  chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
  icu_lld_enable(icup);
  icup->state = ICU_WAITING;
  chSysUnlock();
}

/**
 * @brief   Disables the input capture.
 *
 * @param[in] icup      pointer to the @p ICUDriver object
 *
 * @api
 */
void icuDisable(ICUDriver *icup) {

  chDbgCheck(icup != NULL, "icuDisable");

  chSysLock();
  chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
              (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
              "icuDisable(), #1", "invalid state");
  icu_lld_disable(icup);
  icup->state = ICU_READY;
  chSysUnlock();
}

#endif /* HAL_USE_ICU */

/** @} */
¦å®šç¾©ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚`_kb()` サフィックスã¯ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰/リビジョンレベルã§ä½¿ã†ã“ã¨ã‚’æ„図ã—ã¦ãŠã‚Šã€ä¸€æ–¹ã§ `_user()` サフィックスã¯ã‚­ãƒ¼ãƒžãƒƒãƒ—レベルã§ä½¿ã‚れるã¹ãã§ã™ã€‚ キーボード/リビジョンレベルã§é–¢æ•°ã‚’定義ã™ã‚‹å ´åˆã€`_kb()` ã¯ä»–ã®ä½•ã‹ã‚’実行ã™ã‚‹å‰ã« `_user()` を呼ã³å‡ºã™ã‚ˆã†å®Ÿè£…ã™ã‚‹ã“ã¨ãŒé‡è¦ã§ã™ã€‚ãã†ã§ãªã‘れã°ã€ã‚­ãƒ¼ãƒžãƒƒãƒ—レベル関数ã¯å‘¼ã°ã‚Œãªã„ã§ã—ょã†ã€‚ # カスタムキーコード 最も一般的ãªã‚¿ã‚¹ã‚¯ã¯ã€æ—¢å­˜ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã®æŒ™å‹•を変更ã™ã‚‹ã‹ã€æ–°ã—ã„キーコードを作æˆã™ã‚‹ã“ã¨ã§ã™ã€‚コードã®è¦³ç‚¹ã‹ã‚‰ã¯ã€ãれãžã‚Œã®ä»•組ã¿ã¯éžå¸¸ã«ä¼¼ã¦ã„ã¾ã™ã€‚ ## æ–°ã—ã„キーコードã®å®šç¾© 独自ã®ã‚«ã‚¹ã‚¿ãƒ ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’作æˆã™ã‚‹æœ€åˆã®ã‚¹ãƒ†ãƒƒãƒ—ã¯ã€ãれらを列挙ã™ã‚‹ã“ã¨ã§ã™ã€‚ã“れã¯ã€ã‚«ã‚¹ã‚¿ãƒ ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã«åå‰ã‚’付ã‘ã€ãã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã«ãƒ¦ãƒ‹ãƒ¼ã‚¯ãªç•ªå·ã‚’割り当ã¦ã‚‹ã“ã¨ã®ä¸¡æ–¹ã‚’æ„味ã—ã¾ã™ã€‚QMK ã¯ã€ã‚«ã‚¹ã‚¿ãƒ ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’固定範囲ã®ç•ªå·ã«åˆ¶é™ã™ã‚‹ã®ã§ã¯ãªãã€`SAFE_RANGE` マクロをæä¾›ã—ã¾ã™ã€‚カスタムキーコードを列挙ã™ã‚‹æ™‚ã« `SAFE_RANGE` を使ã†ã¨ã€ãƒ¦ãƒ‹ãƒ¼ã‚¯ãªç•ªå·ã‚’å–å¾—ã™ã‚‹ã“ã¨ãŒä¿è¨¼ã•れã¾ã™ã€‚ ã“れã¯2ã¤ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’列挙ã™ã‚‹ä¾‹ã§ã™ã€‚ã“ã®ãƒ–ロックを `keymap.c` ã«è¿½åŠ ã—ãŸå¾Œã§ã€ã‚­ãƒ¼ãƒžãƒƒãƒ—ã®ä¸­ã§ `FOO` 㨠`BAR` を使ã†ã“ã¨ãŒã§ãã¾ã™ã€‚ ```c enum my_keycodes { FOO = SAFE_RANGE, BAR }; ``` ## ä»»æ„ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã®æŒ™å‹•ã®ãƒ—ログラミング :id=programming-the-behavior-of-any-keycode 既存ã®ã‚­ãƒ¼ã®æŒ™å‹•を上書ãã—ãŸã„å ´åˆã€ã‚ã‚‹ã„ã¯æ–°ã—ã„キーã«ã¤ã„ã¦æŒ™å‹•を定義ã™ã‚‹å ´åˆã€`process_record_kb()` ãŠã‚ˆã³ `process_record_user()` 関数を使ã†ã¹ãã§ã™ã€‚ã“れらã¯å®Ÿéš›ã®ã‚­ãƒ¼ã‚¤ãƒ™ãƒ³ãƒˆãŒå‡¦ç†ã•れるå‰ã®ã‚­ãƒ¼å‡¦ç†ä¸­ã« QMK ã«ã‚ˆã£ã¦å‘¼ã³å‡ºã•れã¾ã™ã€‚ã“れらã®é–¢æ•°ãŒ `true` ã‚’è¿”ã™å ´åˆã€QMK ã¯ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’通常通りã«å‡¦ç†ã—ã¾ã™ã€‚ã“れã¯ã€ã‚­ãƒ¼ã‚’ç½®ãæ›ãˆã‚‹ã®ã§ã¯ãªãã€ã‚­ãƒ¼ã®æ©Ÿèƒ½ã‚’æ‹¡å¼µã™ã‚‹ã®ã«ä¾¿åˆ©ã§ã™ã€‚ã“れらã®é–¢æ•°ãŒ `false` ã‚’è¿”ã™å ´åˆã€QMK ã¯é€šå¸¸ã®ã‚­ãƒ¼å‡¦ç†ã‚’スキップã—ã€å¿…è¦ãªã‚­ãƒ¼ã®ã‚¢ãƒƒãƒ—ã¾ãŸã¯ãƒ€ã‚¦ãƒ³ã‚¤ãƒ™ãƒ³ãƒˆã‚’é€ä¿¡ã™ã‚‹ã®ã‹ã¯ãƒ¦ãƒ¼ã‚¶æ¬¡ç¬¬ã§ã™ã€‚ ã“れらã®é–¢æ•°ã¯ã‚­ãƒ¼ãŒæŠ¼ã•ã‚Œã‚‹ã‹æ”¾ã•れるãŸã³ã«å‘¼ã³å‡ºã•れã¾ã™ã€‚ ### `process_record_user()` ã®å®Ÿè£…例 ã“ã®ä¾‹ã¯2ã¤ã®äº‹ã‚’行ã„ã¾ã™ã€‚`FOO` ã¨å‘¼ã°ã‚Œã‚‹ã‚«ã‚¹ã‚¿ãƒ ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã®æŒ™å‹•を定義ã—ã€Enter ã‚­ãƒ¼ãŒæŠ¼ã•れるãŸã³ã«éŸ³ã‚’å†ç”Ÿã—ã¾ã™ã€‚ ```c bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case FOO: if (record->event.pressed) { // 押ã•ã‚ŒãŸæ™‚ã«ä½•ã‹ã‚’ã—ã¾ã™ } else { // 放ã•ã‚ŒãŸæ™‚ã«ä½•ã‹ã‚’ã—ã¾ã™ } return false; // ã“ã®ã‚­ãƒ¼ã®ä»¥é™ã®å‡¦ç†ã‚’スキップã—ã¾ã™ case KC_ENTER: // enter ãŒæŠ¼ã•ã‚ŒãŸæ™‚ã«éŸ³ã‚’å†ç”Ÿã—ã¾ã™ if (record->event.pressed) { PLAY_SONG(tone_qwerty); } return true; // QMK ã« enter ã®ãƒ—レスã¾ãŸã¯ãƒªãƒªãƒ¼ã‚¹ã‚¤ãƒ™ãƒ³ãƒˆã‚’é€ä¿¡ã•ã›ã¾ã™ default: return true; // ä»–ã®å…¨ã¦ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’通常通りã«å‡¦ç†ã—ã¾ã™ } } ``` ### `process_record_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` * キーマップ: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` `keycode` 引数ã¯ã‚­ãƒ¼ãƒžãƒƒãƒ—ã§å®šç¾©ã•れã¦ã„ã‚‹ã‚‚ã®ã§ã™ã€‚例ãˆã° `MO(1)`ã€`KC_L` ãªã©ã€‚ã“れらã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’処ç†ã™ã‚‹ã«ã¯ `switch...case` ブロックを使ã†ã¹ãã§ã™ã€‚ `record` 引数ã¯å®Ÿéš›ã®ãƒ—レスã«é–¢ã™ã‚‹æƒ…報をå«ã¿ã¾ã™: ```c keyrecord_t record { keyevent_t event { keypos_t key { uint8_t col uint8_t row } bool pressed uint16_t time } } ``` # LED 制御 QMK 㯠HID 仕様ã§å®šç¾©ã•れãŸ5ã¤ã® LED ã®èª­ã¿å–りメソッドをæä¾›ã—ã¾ã™: * Num Lock * Caps Lock * Scroll Lock * Compose * Kana ロック LED ã®çŠ¶æ…‹ã‚’å–å¾—ã™ã‚‹ã«ã¯2ã¤ã®æ–¹æ³•ãŒã‚りã¾ã™: * `bool led_update_kb(led_t led_state)` ã‚ã‚‹ã„㯠`_user(led_t led_state)` を実装ã™ã‚‹ã€ã¾ãŸã¯ * `led_t host_keyboard_led_state()` を呼ã³å‡ºã™ !> `host_keyboard_led_state()` 㯠`led_update_user()` ãŒå‘¼ã°ã‚Œã‚‹å‰ã«æ–°ã—ã„値を既ã«å映ã—ã¦ã„ã‚‹å ´åˆãŒã‚りã¾ã™ã€‚ LED ã®çŠ¶æ…‹ã‚’ `uint8_t` ã¨ã—ã¦æä¾›ã™ã‚‹2ã¤ã®éžæŽ¨å¥¨ã®é–¢æ•°ãŒã‚りã¾ã™: * `uint8_t led_set_kb(uint8_t usb_led)` 㨠`_user(uint8_t usb_led)` * `uint8_t host_keyboard_leds()` ## `led_update_user()` ã“ã®é–¢æ•°ã¯ã“れら5ã¤ã® LED ã®ã„ãšã‚Œã‹ã®çŠ¶æ…‹ãŒå¤‰åŒ–ã™ã‚‹ã¨å‘¼ã°ã‚Œã¾ã™ã€‚LED ã®çŠ¶æ…‹ã‚’æ§‹é€ ä½“ã®ãƒ‘ラメータã¨ã—ã¦å—ã‘å–りã¾ã™ã€‚ 慣例ã«ã‚ˆã‚Šã€`led_update_kb()` ã«ãã®ã‚³ãƒ¼ãƒ‰ã‚’実行ã™ã‚‹ã‚ˆã†ãƒ•ックã•ã›ã‚‹ãŸã‚ã« `led_update_user()` ã‹ã‚‰ `true` ã‚’è¿”ã—ã€`led_update_kb()` ã§ã‚³ãƒ¼ãƒ‰ã‚’実行ã—ãŸããªã„å ´åˆã¯ `false` ã‚’è¿”ã—ã¾ã™ã€‚ 以下ã¯ã„ãã¤ã‹ã®ä¾‹ã§ã™: - レイヤー表示ã®ã‚ˆã†ãªä½•ã‹ã®ãŸã‚ã« LED を使ã†ãŸã‚ã« LED を上書ãã™ã‚‹ - `_kb()` 関数を実行ã—ãŸããªã„ã®ã§ã€`false` ã‚’è¿”ã—ã¾ã™ã€‚ã“れã¯ãƒ¬ã‚¤ãƒ¤ãƒ¼ã®æŒ™å‹•を上書ãã™ã‚‹ãŸã‚ã§ã™ã€‚ - LED ãŒã‚ªãƒ³ã‚ã‚‹ã„ã¯ã‚ªãƒ•ã«ãªã£ãŸæ™‚ã«éŸ³æ¥½ã‚’å†ç”Ÿã™ã‚‹ã€‚ - `_kb` 関数を実行ã—ãŸã„ã®ã§ã€`true` ã‚’è¿”ã—ã¾ã™ã€‚ã“れã¯ãƒ‡ãƒ•ォルト㮠LED ã®æŒ™å‹•ã«è¿½åŠ ã•れã¾ã™ã€‚ ?> `led_set_*` 関数㯠`bool` ã®ä»£ã‚り㫠`void` ã‚’è¿”ã™ãŸã‚ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã® LED 制御を上書ãã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。従ã£ã¦ã€ä»£ã‚り㫠`led_update_*` を使ã†ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚ ### `led_update_kb()` ã®å®Ÿè£…例 ```c bool led_update_kb(led_t led_state) { bool res = led_update_user(led_state); if(res) { // writePin 㯠1 ã§ãƒ”ンを high ã«ã€0 ã§ low ã«è¨­å®šã—ã¾ã™ã€‚ // ã“ã®ä¾‹ã§ã¯ã€ãƒ”ンã¯å転ã—ã¦ã„ã¦ã€ // low/0 㯠LED ãŒã‚ªãƒ³ã«ãªã‚Šã€high/1 㯠LED ãŒã‚ªãƒ•ã«ãªã‚Šã¾ã™ã€‚ // ã“ã®æŒ™å‹•ã¯ã€LED ãŒãƒ”ン㨠VCC ã®é–“ã«ã‚ã‚‹ã‹ã€ãƒ”ン㨠GND ã®é–“ã«ã‚ã‚‹ã‹ã©ã†ã‹ã«ä¾å­˜ã—ã¾ã™ã€‚ writePin(B0, !led_state.num_lock); writePin(B1, !led_state.caps_lock); writePin(B2, !led_state.scroll_lock); writePin(B3, !led_state.compose); writePin(B4, !led_state.kana); } return res; } ``` ### `led_update_user()` ã®å®Ÿè£…例 ã“ã®ä¸å®Œå…¨ãªä¾‹ã¯ Caps Lock ãŒã‚ªãƒ³ã¾ãŸã¯ã‚ªãƒ•ã«ãªã£ãŸå ´åˆã«éŸ³ã‚’å†ç”Ÿã—ã¾ã™ã€‚ã¾ãŸ LED ã®çŠ¶æ…‹ã‚’ä¿æŒã™ã‚‹å¿…è¦ãŒã‚ã‚‹ãŸã‚ã€`true` ã‚’è¿”ã—ã¾ã™ã€‚ ```c #ifdef AUDIO_ENABLE float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); #endif bool led_update_user(led_t led_state) { #ifdef AUDIO_ENABLE static uint8_t caps_state = 0; if (caps_state != led_state.caps_lock) { led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); caps_state = led_state.caps_lock; } #endif return true; } ``` ### `led_update_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `bool led_update_kb(led_t led_state)` * キーマップ: `bool led_update_user(led_t led_state)` ## `host_keyboard_led_state()` 最後ã«å—ä¿¡ã—㟠LED ã®çŠ¶æ…‹ã‚’ `led_t` ã¨ã—ã¦å–å¾—ã™ã‚‹ãŸã‚ã«ã“ã®é–¢æ•°ã‚’呼ã³ã¾ã™ã€‚ã“れã¯ã€`led_update_*` ã®å¤–部ã‹ã‚‰ã€ä¾‹ãˆã° [`matrix_scan_user()`](#matrix-scanning-code) ã®ä¸­ã§ LED ã®çŠ¶æ…‹ã‚’èª­ã¿å–ã‚‹ã®ã«ä¾¿åˆ©ã§ã™ã€‚ ## 物ç†çš„㪠LED ã®çŠ¶æ…‹ã®è¨­å®š 一部ã®ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã®å®Ÿè£…ã¯ã€ç‰©ç†çš„㪠LED ã®çŠ¶æ…‹ã‚’è¨­å®šã™ã‚‹ãŸã‚ã®ä¾¿åˆ©ãªãƒ¡ã‚½ãƒƒãƒ‰ã‚’æä¾›ã—ã¦ã„ã¾ã™ã€‚ ### Ergodox キーボード Ergodox ã®å®Ÿè£…ã¯ã€å€‹ã€…ã® LED をオンã‚ã‚‹ã„ã¯ã‚ªãƒ•ã«ã™ã‚‹ãŸã‚ã« `ergodox_right_led_1`/`2`/`3_on`/`off()` ã¨ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã«ã‚ˆã£ã¦ãれらをオンã‚ã‚‹ã„ã¯ã‚ªãƒ•ã«ã™ã‚‹ãŸã‚ã« `ergodox_right_led_on`/`off(uint8_t led)` ã‚’æä¾›ã—ã¾ã™ã€‚ ã•らã«ã€LED ã®æ˜Žåº¦ã‚’指定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚å…¨ã¦ã® LED ã«åŒã˜æ˜Žåº¦ã‚’指定ã™ã‚‹ãªã‚‰ `ergodox_led_all_set(uint8_t n)` を使ã„ã€å€‹åˆ¥ã® LED ã®æ˜Žåº¦ã‚’指定ã™ã‚‹ãªã‚‰ `ergodox_right_led_1`/`2`/`3_set(uint8_t n)` を使ã„ã€LED ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’指定ã—ã¦æ˜Žåº¦ã‚’指定ã™ã‚‹ã«ã¯ `ergodox_right_led_set(uint8_t led, uint8_t n)` を使ã„ã¾ã™ã€‚ Ergodox キーボードã¯ã€æœ€ä½Žã®æ˜Žåº¦ã¨ã—㦠`LED_BRIGHTNESS_LO` ã‚’ã€æœ€é«˜ã®è¼åº¦(ã“れã¯ãƒ‡ãƒ•ォルトã§ã™)ã¨ã—㦠`LED_BRIGHTNESS_HI` も定義ã—ã¦ã„ã¾ã™ã€‚ # キーボードã®åˆæœŸåŒ–コード キーボードã®åˆæœŸåŒ–プロセスã«ã¯å¹¾ã¤ã‹ã®ã‚¹ãƒ†ãƒƒãƒ—ãŒã‚りã¾ã™ã€‚何をã—ãŸã„ã‹ã«ã‚ˆã£ã¦ã€ã©ã®é–¢æ•°ã‚’使ã†ã¹ãã‹ã«å½±éŸ¿ã—ã¾ã™ã€‚ 3ã¤ã®ä¸»ãªåˆæœŸåŒ–関数ãŒã‚りã€å‘¼ã³å‡ºã•れる順番ã«ãƒªã‚¹ãƒˆã•れã¦ã„ã¾ã™ã€‚ * `keyboard_pre_init_*` - ã»ã¨ã‚“ã©ã®ã‚‚ã®ãŒé–‹å§‹ã•れるå‰ã«èµ·ã“りã¾ã™ã€‚éžå¸¸ã«æ—©ãã«å®Ÿè¡Œã—ãŸã„ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã«é©ã—ã¦ã„ã¾ã™ã€‚ * `matrix_init_*` - ファームウェアã®ã‚¹ã‚¿ãƒ¼ãƒˆã‚¢ãƒƒãƒ—プロセスã®é€”中ã§èµ·ã“りã¾ã™ã€‚ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã¯åˆæœŸåŒ–ã•れã¾ã™ãŒã€æ©Ÿèƒ½ã¯ã¾ã åˆæœŸåŒ–ã•れã¦ã„ãªã„å ´åˆãŒã‚りã¾ã™ã€‚ * `keyboard_post_init_*` - ファームウェアã®ã‚¹ã‚¿ãƒ¼ãƒˆã‚¢ãƒƒãƒ—ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¾Œã«èµ·ã“りã¾ã™ã€‚ã“れã¯ã»ã¨ã‚“ã©ã®å ´åˆã€ "カスタマイズ"コードをé…ç½®ã™ã‚‹å ´æ‰€ã§ã™ã€‚ !> ã»ã¨ã‚“ã©ã®äººã«ã¨ã£ã¦ã€`keyboard_post_init_user` ãŒå‘¼ã³å‡ºã—ãŸã„ã‚‚ã®ã§ã™ã€‚例ãˆã°ã€ã“ã“ã§ RGB アンダーグローã®ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—を行ã„ã¾ã™ã€‚ ## キーボードã®äº‹å‰åˆæœŸåŒ–コード ã“れ㯠USB ã•ãˆèµ·å‹•ã™ã‚‹å‰ã®ã€èµ·å‹•中ã®éžå¸¸ã«æ—©ã„段階ã§å®Ÿè¡Œã•れã¾ã™ã€‚ ã“ã®ç›´å¾Œã«ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ãŒåˆæœŸåŒ–ã•れã¾ã™ã€‚ ã“れã¯ä¸»ã«ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å‘ãã®åˆæœŸåŒ–ã®ãŸã‚ã§ã‚ã‚‹ãŸã‚ã€ã»ã¨ã‚“ã©ã®ãƒ¦ãƒ¼ã‚¶ã¯ä½¿ã†ã¹ãã§ã¯ã‚りã¾ã›ã‚“。 ãŸã ã—ã€åˆæœŸåŒ–ãŒå¿…è¦ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚ã‚‹å ´åˆã«ã¯ã€ã“ã‚ŒãŒæœ€é©ãªå ´æ‰€ã§ã™ (LED ピンã®åˆæœŸåŒ–ãªã©)。 ### `keyboard_pre_init_user()` ã®å®Ÿè£…例 ã“ã®ä¾‹ã¯ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ãƒ¬ãƒ™ãƒ«ã§ã€LED ピンã¨ã—㦠B0ã€B1ã€B2ã€B3 ãŠã‚ˆã³ B4 をセットアップã—ã¾ã™ã€‚ ```c void keyboard_pre_init_user(void) { // キーボードã®äº‹å‰åˆæœŸã‚³ãƒ¼ãƒ‰ã‚’呼ã³å‡ºã—ã¾ã™ã€‚ // LED ピンを出力ã¨ã—ã¦è¨­å®šã—ã¾ã™ setPinOutput(B0); setPinOutput(B1); setPinOutput(B2); setPinOutput(B3); setPinOutput(B4); } ``` ### `keyboard_pre_init_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `void keyboard_pre_init_kb(void)` * キーマップ: `void keyboard_pre_init_user(void)` ## マトリックスã®åˆæœŸåŒ–コード ã“れã¯ã€ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ãŒåˆæœŸåŒ–ã•れã€ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ä¸€éƒ¨ãŒã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã•れãŸå¾Œã§ã€ãŸã ã—機能ã®å¤šããŒåˆæœŸåŒ–ã•れるå‰ã«ã€å‘¼ã³å‡ºã•れã¾ã™ã€‚ ä»–ã®å ´æ‰€ã§å¿…è¦ã«ãªã‚‹ã‹ã‚‚ã—れãªã„ã‚‚ã®ã‚’セットアップã™ã‚‹ã®ã«å½¹ç«‹ã¡ã¾ã™ãŒã€ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã«é–¢é€£ã™ã‚‹ã‚‚ã®ã§ã¯ãªãã€é–‹å§‹å ´æ‰€ã«ä¾å­˜ã™ã‚‹ã‚‚ã®ã§ã‚‚ã‚りã¾ã›ã‚“。 ### `matrix_init_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `void matrix_init_kb(void)` * キーマップ: `void matrix_init_user(void)` ## キーボードã®äº‹å¾ŒåˆæœŸåŒ–コード キーボードã®åˆæœŸåŒ–ãƒ—ãƒ­ã‚»ã‚¹ã®æ¥µã‚ã¦æœ€å¾Œã®ã‚¿ã‚¹ã‚¯ã¨ã—ã¦å®Ÿè¡Œã•れã¾ã™ã€‚ã“ã®æ™‚点ã§åˆæœŸåŒ–ã•れる必è¦ãŒã‚るよã†ãªã€ç‰¹å®šã®æ©Ÿèƒ½ã‚’変更ã—ãŸã„å ´åˆã«ä¾¿åˆ©ã§ã™ã€‚ ### `keyboard_post_init_user()` ã®å®Ÿè£…例 ã“ã®ä¾‹ã¯ã€ä»–ã®å…¨ã¦ã®ã‚‚ã®ãŒåˆæœŸåŒ–ã•れãŸå¾Œã§å®Ÿè¡Œã•れã€rgb アンダーグローã®è¨­å®šã‚’セットアップã—ã¾ã™ã€‚ ```c void keyboard_post_init_user(void) { // post init コードを呼ã³ã¾ã™ rgblight_enable_noeeprom(); // 設定をä¿å­˜ã›ãšã« Rgb を有効ã«ã—ã¾ã™ rgblight_sethsv_noeeprom(180, 255, 255); // ä¿å­˜ã›ãšã«è‰²ã‚’é’ç·‘/シアンã«è¨­å®šã—ã¾ã™ rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // ä¿å­˜ã›ãšã«ãƒ¢ãƒ¼ãƒ‰ã‚’高速ãªãƒ–リージングã«è¨­å®šã—ã¾ã™ } ``` ### `keyboard_post_init_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `void keyboard_post_init_kb(void)` * キーマップ: `void keyboard_post_init_user(void)` # マトリックススキャンコード :id=matrix-scanning-code å¯èƒ½ã§ã‚れã°å¸¸ã« `process_record_*()` を使ã£ã¦ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã‚’カスタマイズã—ã€ãã®æ–¹æ³•ã§ã‚¤ãƒ™ãƒ³ãƒˆã‚’フックã—ã€ã‚³ãƒ¼ãƒ‰ãŒã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã®ãƒ‘ãƒ•ã‚©ãƒ¼ãƒžãƒ³ã‚¹ã«æ‚ªå½±éŸ¿ã‚’与ãˆãªã„よã†ã«ã—ã¾ã™ã€‚ãŸã ã—ã€ã¾ã‚Œã«ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ã«ãƒ•ックã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã“れらã®é–¢æ•°ã¯1ç§’ã‚ãŸã‚Šå°‘ãªãã¨ã‚‚10回ã¯å‘¼ã³å‡ºã•れるãŸã‚ã€ã“れらã®é–¢æ•°ã®ã‚³ãƒ¼ãƒ‰ã®ãƒ‘フォーマンスã«éžå¸¸ã«æ³¨æ„ã—ã¦ãã ã•ã„。 ### `matrix_scan_*` ã®å®Ÿè£…例 ã“ã®ä¾‹ã¯æ„図的ã«çœç•¥ã•れã¦ã„ã¾ã™ã€‚ã“ã®ã‚ˆã†ãªãƒ‘ãƒ•ã‚©ãƒ¼ãƒžãƒ³ã‚¹ã«æ•感ãªé ˜åŸŸã«ãƒ•ックã™ã‚‹å‰ã«ã€ä¾‹ã‚’使ã‚ãšã«ã“れを書ããŸã‚ã«ã€QMK 内部ã«ã¤ã„ã¦å分ç†è§£ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚助ã‘ãŒå¿…è¦ã§ã‚れã°ã€[issue ã‚’é–‹ã](https://github.com/qmk/qmk_firmware/issues/new) ã‹ [Discord ã§ä¼šè©±](https://discord.gg/Uq7gcHh)ã—ã¦ãã ã•ã„。 ### `matrix_scan_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `void matrix_scan_kb(void)` * キーマップ: `void matrix_scan_user(void)` ã“ã®é–¢æ•°ã¯ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ã®ãŸã³ã«å‘¼ã³å‡ºã•れã¾ã™ã€‚ã“れã¯åŸºæœ¬çš„ã« MCU ãŒå‡¦ç†ã§ãる頻度ã§ã™ã€‚大é‡ã«å®Ÿè¡Œã•れるãŸã‚ã€ã“ã“ã«ä½•ã‚’ç½®ãã‹ã«ã¤ã„ã¦ã¯æ³¨æ„ã—ã¦ãã ã•ã„。 カスタムマトリックススキャンコードãŒå¿…è¦ãªå ´åˆã¯ã€ã“ã®é–¢æ•°ã‚’使ã†å¿…è¦ãŒã‚りã¾ã™ã€‚ã¾ãŸã€ã‚«ã‚¹ã‚¿ãƒ ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹å‡ºåŠ› (LED ã‚ã‚‹ã„ã¯ãƒ‡ã‚£ã‚¹ãƒ—レイãªã©)ã‚„ã€ãƒ¦ãƒ¼ã‚¶ãŒå…¥åŠ›ã—ã¦ã„ãªã„å ´åˆã§ã‚‚定期的ã«ãƒˆãƒªã‚¬ãƒ¼ã™ã‚‹ãã®ä»–ã®æ©Ÿèƒ½ã®ãŸã‚ã«ä½¿ã†ã“ã¨ãŒã§ãã¾ã™ã€‚ # キーボードアイドリング/ウェイクコード キーボードãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹å ´åˆã€å¤šãã®æ©Ÿèƒ½ã‚’åœæ­¢ã™ã‚‹ã“ã¨ã§"アイドル"ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れã®è‰¯ã„例ã¯ã€RGB ライトã‚ã‚‹ã„ã¯ãƒãƒƒã‚¯ãƒ©ã‚¤ãƒˆã§ã™ã€‚ã“れã«ã‚ˆã‚Šã€é›»åŠ›æ¶ˆè²»ã‚’ç¯€ç´„ã§ãã‚‹ã‹ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã®å‹•ä½œãŒæ”¹å–„ã•れるã‹ã‚‚ã—れã¾ã›ã‚“。 ã“れã¯2ã¤ã®é–¢æ•°ã«ã‚ˆã£ã¦åˆ¶å¾¡ã•れã¾ã™: `suspend_power_down_*` ãŠã‚ˆã³ `suspend_wakeup_init_*`。ã“れらã¯ã‚·ã‚¹ãƒ†ãƒ ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ãŒã‚¢ã‚¤ãƒ‰ãƒ«ã«ãªã£ãŸæ™‚ã¨ã€èµ·å‹•ã—ãŸæ™‚ã®ãれãžã‚Œã§å‘¼ã°ã‚Œã¾ã™ã€‚ ### suspend_power_down_user() 㨠suspend_wakeup_init_user() ã®å®Ÿè£…例 ```c void suspend_power_down_user(void) { rgb_matrix_set_suspend_state(true); } void suspend_wakeup_init_user(void) { rgb_matrix_set_suspend_state(false); } ``` ### キーボードサスペンド/ウェイク関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン : `void suspend_power_down_kb(void)` ãŠã‚ˆã³ `void suspend_wakeup_init_user(void)` * キーマップ: `void suspend_power_down_kb(void)` ãŠã‚ˆã³ `void suspend_wakeup_init_user(void)` # レイヤー切り替ãˆã‚³ãƒ¼ãƒ‰ :id=layer-change-code ã“れã¯ãƒ¬ã‚¤ãƒ¤ãƒ¼ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã‚‹ãŸã³ã«ã‚³ãƒ¼ãƒ‰ã‚’実行ã—ã¾ã™ã€‚レイヤー表示ã‚ã‚‹ã„ã¯ã‚«ã‚¹ã‚¿ãƒ ãƒ¬ã‚¤ãƒ¤ãƒ¼å‡¦ç†ã«å½¹ç«‹ã¡ã¾ã™ã€‚ ### `layer_state_set_*` ã®å®Ÿè£…例 ã“ã®ä¾‹ã¯ã€ãƒ¬ã‚¤ãƒ¤ãƒ¼ã«åŸºã¥ã„㦠[RGB アンダーグロー](ja/feature_rgblight.md)を設定ã™ã‚‹æ–¹æ³•を示ã—ã¦ã„ã¦ã€Planck を例ã¨ã—ã¦ä½¿ã£ã¦ã„ã¾ã™ã€‚ ```c layer_state_t layer_state_set_user(layer_state_t state) { switch (get_highest_layer(state)) { case _RAISE: rgblight_setrgb (0x00, 0x00, 0xFF); break; case _LOWER: rgblight_setrgb (0xFF, 0x00, 0x00); break; case _PLOVER: rgblight_setrgb (0x00, 0xFF, 0x00); break; case _ADJUST: rgblight_setrgb (0x7A, 0x00, 0xFF); break; default: // ä»–ã®å…¨ã¦ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚ã‚‹ã„ã¯ãƒ‡ãƒ•ォルトã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ rgblight_setrgb (0x00, 0xFF, 0xFF); break; } return state; } ``` 特定ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã®çŠ¶æ…‹ã‚’ç¢ºèªã™ã‚‹ã«ã¯ã€ `IS_LAYER_ON_STATE(state, layer)` 㨠`IS_LAYER_OFF_STATE(state, layer)` マクロを使ã„ã¾ã™ã€‚ `layer_state_set_*` 関数ã®å¤–ã§ã¯ã€ã‚°ãƒ­ãƒ¼ãƒãƒ«ãªãƒ¬ã‚¤ãƒ¤ãƒ¼çŠ¶æ…‹ã‚’ç¢ºèªã™ã‚‹ãŸã‚ã« `IS_LAYER_ON(layer)` 㨠`IS_LAYER_OFF(layer)` マクロを使ãˆã¾ã™ã€‚ ### `layer_state_set_*` 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `layer_state_t layer_state_set_kb(layer_state_t state)` * キーマップ: `layer_state_t layer_state_set_user(layer_state_t state)` [ã‚­ãƒ¼ãƒžãƒƒãƒ—ã®æ¦‚è¦](ja/keymap.md#keymap-layer-status)ã§èª¬æ˜Žã•れるよã†ã«ã€`state` ã¯ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªãƒ¬ã‚¤ãƒ¤ãƒ¼ã®ãƒ“ットマスクã§ã™ã€‚ # 永続的ãªè¨­å®š (EEPROM) ã“れã«ã‚ˆã‚Šã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã®ãŸã‚ã®æ°¸ç¶šçš„ãªè¨­å®šã‚’設定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れらã®è¨­å®šã¯ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ã® EEPROM ã«ä¿å­˜ã•れã€é›»æºãŒè½ã¡ãŸå¾Œã§ã‚ã£ã¦ã‚‚ä¿æŒã•れã¾ã™ã€‚設定㯠`eeconfig_read_kb` ãŠã‚ˆã³ `eeconfig_read_user` を使ã£ã¦èª­ã¿å–ã‚‹ã“ã¨ãŒã§ãã€`eeconfig_update_kb` ãŠã‚ˆã³ `eeconfig_update_user` を使ã£ã¦æ›¸ãã“ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れã¯åˆ‡ã‚Šæ›¿ãˆå¯èƒ½ãªæ©Ÿèƒ½ (rgb レイヤーã®è¡¨ç¤ºã®åˆ‡ã‚Šæ›¿ãˆãªã©)ã«å½¹ç«‹ã¡ã¾ã™ã€‚ã•らã«ã€`eeconfig_init_kb` ãŠã‚ˆã³ `eeconfig_init_user` を使ã£ã¦ EEPROM ã®ãƒ‡ãƒ•ォルト値を設定ã§ãã¾ã™ã€‚ ã“ã“ã§ã®è¤‡é›‘ãªéƒ¨åˆ†ã¯ã€EEPROM を介ã—ã¦ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ãŠã‚ˆã³ã‚¢ã‚¯ã‚»ã‚¹ã§ãる方法ãŒãŸãã•ã‚“ã‚りã€ã“れを行ã†ãŸã‚ã®"æ­£ã—ã„"方法ãŒç„¡ã„ã¨ã„ã†ã“ã¨ã§ã™ã€‚ãŸã ã—ã€å„関数ã«ã¯ DWORD (4 ãƒã‚¤ãƒˆ)ã—ã‹ã‚りã¾ã›ã‚“。 EEPROM ã®æ›¸ãè¾¼ã¿å›žæ•°ã«ã¯åˆ¶é™ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。ã“れã¯éžå¸¸ã«é«˜ã„値ã§ã™ãŒã€EEPROM ã«æ›¸ã込むã®ã¯ã“れã ã‘ã§ã¯ãªãã€ã‚‚ã—é »ç¹ã«æ›¸ã込むã¨ã€MCU ã®å¯¿å‘½ã‚’大幅ã«çŸ­ãã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ * ã“ã®ä¾‹ã‚’ç†è§£ã—ã¦ã„ãªã„å ´åˆã¯ã€ã“ã®æ©Ÿèƒ½ã¯ã‹ãªã‚Šè¤‡é›‘ãªãŸã‚ã€ã“ã®æ©Ÿèƒ½ã‚’使ã†ã“ã¨ã‚’é¿ã‘ã¦ã‚‚æ§‹ã„ã¾ã›ã‚“。 ### 実装例 ã“れã¯ã€è¨­å®šã‚’追加ã—ã€èª­ã¿æ›¸ãã™ã‚‹ä¾‹ã§ã™ã€‚ã“ã®ä¾‹ã§ã¯ã€ãƒ¦ãƒ¼ã‚¶ã‚­ãƒ¼ãƒžãƒƒãƒ—を使ã£ã¦ã„ã¾ã™ã€‚ã“れã¯è¤‡é›‘ãªæ©Ÿèƒ½ã§ã€å¤šãã®ã“ã¨ãŒè¡Œã‚れã¦ã„ã¾ã™ã€‚実際ã€å‹•作ã®ãŸã‚ã«ä¸Šè¨˜ã®å¤šãã®é–¢æ•°ã‚’使ã„ã¾ã™ï¼ keymap.c ファイルã®ä¸­ã§ã€å…ˆé ­ã«ã“れを追加ã—ã¾ã™: ```c typedef union { uint32_t raw; struct { bool rgb_layer_change :1; }; } user_config_t; user_config_t user_config; ``` ã“れã¯ã€è¨­å®šã‚’メモリ内ã«ä¿å­˜ã—ã€EEPROM ã«æ›¸ã込むã“ã¨ãŒã§ãã‚‹32ビット構造体をセットアップã—ã¾ã™ã€‚ã“れを使ã†ã¨ã€ã“ã®æ§‹é€ ä½“ã«å¤‰æ•°ãŒå®šç¾©ã•れるãŸã‚ã€å¤‰æ•°ã‚’定義ã™ã‚‹å¿…è¦ãŒç„¡ããªã‚Šã¾ã™ã€‚`bool` (boolean) ã®å€¤ã¯1ビットを使ã„ã€`uint8_t` ã¯8ビットを使ã„ã€`uint16_t` ã¯16ビットを使ã†ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。組ã¿åˆã‚ã›ã¦ä½¿ã†ã“ã¨ãŒã§ãã¾ã™ãŒã€é †ç•ªã®å¤‰æ›´ã¯èª­ã¿æ›¸ãã•れる値ãŒå¤‰æ›´ã•れるãŸã‚ã€å•題ãŒç™ºç”Ÿã™ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。 `layer_state_set_*` 関数ã®ãŸã‚ã« `rgb_layer_change` を使ã„ã€å…¨ã¦ã‚’設定ã™ã‚‹ãŸã‚ã« `keyboard_post_init_user` ãŠã‚ˆã³ `process_record_user` を使ã„ã¾ã™ã€‚ ã“ã“ã§ã€ä¸Šã® `keyboard_post_init_user` コードを使ã£ã¦ã€ä½œæˆã—ãŸã°ã‹ã‚Šã®æ§‹é€ ä½“を設定ã™ã‚‹ãŸã‚ã« `eeconfig_read_user()` を追加ã—ã¾ã™ã€‚ãã—ã¦ã€ã“ã®æ§‹é€ ä½“ã‚’ã™ãã«ä½¿ã£ã¦ã‚­ãƒ¼ãƒžãƒƒãƒ—ã®æ©Ÿèƒ½ã‚’制御ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ãれã¯ä»¥ä¸‹ã®ã‚ˆã†ã«ãªã‚Šã¾ã™: ```c void keyboard_post_init_user(void) { // キーマップレベルã®ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã®åˆæœŸåŒ–処ç†ã‚’呼ã³ã¾ã™ // EEPROM ã‹ã‚‰ãƒ¦ãƒ¼ã‚¶è¨­å®šã‚’読ã¿è¾¼ã¿ã¾ã™ user_config.raw = eeconfig_read_user(); // 有効ãªå ´åˆã¯ãƒ‡ãƒ•ォルトレイヤーを設定ã—ã¾ã™ if (user_config.rgb_layer_change) { rgblight_enable_noeeprom(); rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } } ``` 上記ã®é–¢æ•°ã¯èª­ã¿å–ã£ãŸã°ã‹ã‚Šã® EEPROM 設定を使ã„ã€ãƒ‡ãƒ•ォルトã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã® RGB 色を設定ã—ã¾ã™ã€‚ãã®ã€Œç”Ÿã®ã€å€¤ã¯ã€ä¸Šã§ä½œæˆã—ãŸã€Œå…±ç”¨ä½“ã€ã«åŸºã¥ã„ã¦ä½¿ç”¨å¯èƒ½ãªæ§‹é€ ã«å¤‰æ›ã•れã¾ã™ã€‚ ```c layer_state_t layer_state_set_user(layer_state_t state) { switch (get_highest_layer(state)) { case _RAISE: if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } break; case _LOWER: if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } break; case _PLOVER: if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } break; case _ADJUST: if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } break; default: // ä»–ã®å…¨ã¦ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚ã‚‹ã„ã¯ãƒ‡ãƒ•ォルトã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } break; } return state; } ``` ã“れã«ã‚ˆã‚Šã€å€¤ãŒæœ‰åйã«ãªã£ã¦ã„ãŸå ´åˆã®ã¿ã€RGB アンダーグローãŒå¤‰æ›´ã•れã¾ã™ã€‚ã“ã®å€¤ã‚’設定ã™ã‚‹ãŸã‚ã«ã€`RGB_LYR` ã¨å‘¼ã°ã‚Œã‚‹ `process_record_user` ç”¨ã®æ–°ã—ã„キーコードを作æˆã—ã¾ã™ã€‚ã•らã«ã€é€šå¸¸ã® RGB コードを使ã†å ´åˆã€ä¸Šè¨˜ã®ä¾‹ã‚’使ã£ã¦ã‚ªãƒ•ã«ãªã‚‹ã“ã¨ã‚’確èªã—ã¾ã™ã€‚以下ã®ã‚ˆã†ã«ãªã‚Šã¾ã™: ```c bool process_record_user(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case FOO: if (record->event.pressed) { // 押ã•ã‚ŒãŸæ™‚ã«ä½•ã‹ã‚’ã—ã¾ã™ } else { // 放ã•ã‚ŒãŸæ™‚ã«ä½•ã‹ã‚’ã—ã¾ã™ } return false; // ã“ã®ã‚­ãƒ¼ã®ä»¥é™ã®å‡¦ç†ã‚’スキップã—ã¾ã™ case KC_ENTER: // enter ãŒæŠ¼ã•ã‚ŒãŸæ™‚ã«éŸ³ã‚’å†ç”Ÿã—ã¾ã™ if (record->event.pressed) { PLAY_SONG(tone_qwerty); } return true; // QMK ã« enter ã®ãƒ—レスã¾ãŸã¯ãƒªãƒªãƒ¼ã‚¹ã‚¤ãƒ™ãƒ³ãƒˆã‚’é€ä¿¡ã•ã›ã¾ã™ case RGB_LYR: // ã“れã«ã‚ˆã‚Šã€ã‚¢ãƒ³ãƒ€ãƒ¼ã‚°ãƒ­ãƒ¼ã‚’レイヤー表示ã¨ã—ã¦ã€ã‚ã‚‹ã„ã¯é€šå¸¸é€šã‚Šã«ä½¿ã†ã“ã¨ãŒã§ãã¾ã™ã€‚ if (record->event.pressed) { user_config.rgb_layer_change ^= 1; // 状態を切り替ãˆã¾ã™ eeconfig_update_user(user_config.raw); // æ–°ã—ã„状態を EEPROM ã«æ›¸ãè¾¼ã¿ã¾ã™ if (user_config.rgb_layer_change) { // レイヤーã®çŠ¶æ…‹è¡¨ç¤ºãŒæœ‰åйãªå ´åˆ layer_state_set(layer_state); // ã™ãã«ãƒ¬ã‚¤ãƒ¤ãƒ¼ã®è‰²ã‚’æ›´æ–°ã—ã¾ã™ } } return false; case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // ä»»æ„ã® RGB コード ã«å¯¾ã—ã¦(quantum_keycodes.h を見ã¦ãã ã•ã„。400行目å‚ç…§) if (record->event.pressed) { // ã“れã¯ãƒ¬ã‚¤ãƒ¤ãƒ¼è¡¨ç¤ºã‚’無効ã«ã—ã¾ã™ã€‚ã“れを変更ã™ã‚‹å ´åˆã¯ã€ç„¡åйã«ã—ãŸã„ã ã‚ã†ãŸã‚。 if (user_config.rgb_layer_change) { // 有効ãªå ´åˆã®ã¿ user_config.rgb_layer_change = false; // 無効ã«ã—ã¾ã™ eeconfig_update_user(user_config.raw); // 設定を EEPROM ã«æ›¸ãè¾¼ã¿ã¾ã™ } } return true; break; default: return true; // ä»–ã®å…¨ã¦ã®ã‚­ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’通常通りã«å‡¦ç†ã—ã¾ã™ } } ``` 最後ã«ã€`eeconfig_init_user` 関数を追加ã—ã¦ã€EEPROM ãŒãƒªã‚»ãƒƒãƒˆã•ã‚ŒãŸæ™‚ã«ãƒ‡ãƒ•ォルト値ã€ã•らã«ã¯ã‚«ã‚¹ã‚¿ãƒ ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’指定ã§ãるよã†ã«ã—ã¾ã™ã€‚EEPROM を強制的ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã«ã¯ã€`EEP_RST` キーコードã‚ã‚‹ã„ã¯[ブートマジック](ja/feature_bootmagic.md)機能を使ã„ã¾ã™ã€‚例ãˆã°ã€ãƒ‡ãƒ•ォルト㧠rgb レイヤー表示を設定ã—ã€ãƒ‡ãƒ•ォルト値をä¿å­˜ã—ãŸã„å ´åˆã€‚ ```c void eeconfig_init_user(void) { // EEPROM ãŒãƒªã‚»ãƒƒãƒˆã•れã¾ã™ï¼ user_config.raw = 0; user_config.rgb_layer_change = true; // デフォルトã§ã“れを有効ã«ã—ã¾ã™ eeconfig_update_user(user_config.raw); // デフォルト値を EEPROM ã«æ›¸ãè¾¼ã¿ã¾ã™ // ã“れらã®å€¤ã‚‚ EEPROM ã«æ›¸ã込むãŸã‚ã«ã¯ã€noeeprom 以外ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’使ã„ã¾ã™ rgblight_enable(); // デフォルト㧠RGB を有効ã«ã—ã¾ã™ rgblight_sethsv_cyan(); // デフォルトã§ã‚·ã‚¢ãƒ³ã«è¨­å®šã—ã¾ã™ rgblight_mode(1); // デフォルトã§ã‚½ãƒªãƒƒãƒ‰ã«è¨­å®šã—ã¾ã™ } ``` ã“れã§å®Œäº†ã§ã™ã€‚RGB レイヤー表示ã¯å¿…è¦ãªå ´åˆã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚キーボードをå–り外ã—ãŸå¾Œã§ã‚‚ä¿å­˜ã•れã¾ã™ã€‚RGB コードã®ã„ãšã‚Œã‹ã‚’使ã†ã¨ã€ãƒ¬ã‚¤ãƒ¤ãƒ¼è¡¨ç¤ºãŒç„¡åйã«ãªã‚Šã€è¨­å®šã—ãŸãƒ¢ãƒ¼ãƒ‰ã¨è‰²ãŒãã®ã¾ã¾ã«ãªã‚Šã¾ã™ã€‚ ### 'EECONFIG' 関数ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ * キーボード/リビジョン: `void eeconfig_init_kb(void)`ã€`uint32_t eeconfig_read_kb(void)` ãŠã‚ˆã³ `void eeconfig_update_kb(uint32_t val)` * キーマップ: `void eeconfig_init_user(void)`ã€`uint32_t eeconfig_read_user(void)` ãŠã‚ˆã³ `void eeconfig_update_user(uint32_t val)` `val` 㯠EEPROM ã«æ›¸ãè¾¼ã¿ãŸã„データã®å€¤ã§ã™ã€‚`eeconfig_read_*` 関数㯠EEPROM ã‹ã‚‰32ビット(DWORD) 値を返ã—ã¾ã™ã€‚