# バックライト

<!---
  original document: 0.9.10:docs/feature_backlight.md
  git diff 0.9.10 HEAD -- docs/feature_backlight.md | cat
-->

多くのキーボードは、キースイッチを貫通して配置されたり、キースイッチの下に配置された個々の LED によって、バックライトキーをサポートします。この機能は通常スイッチごとに単一の色しか使用できないため、[RGB アンダーグロー](ja/feature_rgblight.md)および [RGB マトリックス](ja/feature_rgb_matrix.md)機能のどちらとも異なりますが、キーボードに複数の異なる単一色の LED を取り付けることは当然可能です。

QMK は *パルス幅変調*(*Pulse Width Modulation*) すなわち PWM として知られている技術で急速にオンおよびオフを切り替えることで、これらの LED の輝度を制御できます。PWM 信号のデューティサイクルを変えることで、調光の錯覚を起こすことができます。

MCU は、GPIO ピンにはそんなに電流を供給できません。MCU から直接バックライトに給電せずに、バックライトピンは LED への電力を切り替えるトランジスタあるいは MOSFET に接続されます。

## 機能の設定

ほとんどのキーボードではバックライトをサポートしている場合にデフォルトで有効になっていますが、もし機能しない場合は `rules.mk` が以下を含んでいることを確認してください:

```makefile
BACKLIGHT_ENABLE = yes
```

## キーコード
有効にすると、以下のキーコードを使ってバックライトレベルを変更することができます。

| キー | 説明 |
|---------|------------------------------------------|
| `BL_TOGG` | バックライトをオンあるいはオフにする |
| `BL_STEP` | バックライトレベルを循環する |
| `BL_ON` | バックライトを最大輝度に設定する |
| `BL_OFF` | バックライトをオフにする |
| `BL_INC` | バックライトレベルを上げる |
| `BL_DEC` | バックライトレベルを下げる |
| `BL_BRTG` | バックライトの明滅動作を切り替える |

## バックライト関数群

| 関数 | 説明 |
|----------|-----------------------------------------------------------|
| `backlight_toggle()` | バックライトをオンあるいはオフにする |
| `backlight_enable()` | バックライトをオンにする |
| `backlight_disable()` | バックライトをオフにする |
| `backlight_step()` | バックライトレベルを循環する |
| `backlight_increase()` | バックライトレベルを上げる |
| `backlight_decrease()` | バックライトレベルを下げる |
| `backlight_level(x)` | バックライトのレベルを特定のレベルに設定する |
| `get_backlight_level()` | 現在のバックライトレベルを返す |
| `is_backlight_enabled()` | バックライトが現在オンかどうかを返す |

### バックライトの明滅動作の関数群

| 関数 | 説明 |
|----------|---------------------------------------------------|
| `breathing_toggle()` | バックライトの明滅動作をオンまたはオフにする |
| `breathing_enable()` | バックライトの明滅動作をオンにする |
| `breathing_disable()` | バックライトの明滅動作をオフにする |

## ドライバの設定

どのドライバを使うかを選択するには、以下を使って `rules.mk` を設定します:

```makefile
BACKLIGHT_DRIVER = software # 有効なドライバの値は 'pwm,software,no' です
```

各ドライバについてのヘルプは以下を見てください。

## 共通のドライバ設定

バックライトの挙動を変更するには、`config.h` の中で以下の `#define` をします:

| 定義 | デフォルト | 説明 |
|---------------------|-------------|--------------------------------------------------------------------------------------|
| `BACKLIGHT_LEVELS` | `3` | 輝度のレベルの数 (オフを除いて最大 31) |
| `BACKLIGHT_CAPS_LOCK` | *定義なし* | バックライトを使って Caps Lock のインジケータを有効にする (専用 LED の無いキーボードのため) |
| `BACKLIGHT_BREATHING` | *定義なし* | サポートされる場合は、バックライトの明滅動作を有効にする |
| `BREATHING_PERIOD` | `6` | 各バックライトの "明滅" の長さ（秒） |
| `BACKLIGHT_ON_STATE` | `0` | バックライトが "オン" の時のバックライトピンの状態 - high の場合は `1`、low の場合は `0` |

### バックライトオン状態

ほとんどのバックライトの回路は N チャンネルの MOSFET あるいは NPN トランジスタによって駆動されます。これは、トランジスタを*オン*にして LED を点灯させるには、ゲートまたはベースに接続されているバックライトピンを *high* に駆動する必要があることを意味します。
ただし、P チャンネルの MOSFET あるいは PNP トランジスタが使われる場合があります。この場合、トランジスタがオンの時、ピンは代わりに *low* で駆動されます。

この機能は `BACKLIGHT_ON_STATE` 定義することでキーボードレベルで設定されます。

## AVR ドライバ

AVR ボードでは、デフォルトのドライバは現在のところ最善のシナリオを選択するために構成を探っています。ドライバはデフォルトで設定されますが、rules.mk 内の同等の設定は以下の通りです:
```makefile
BACKLIGHT_DRIVER = pwm
```

### 注意事項

ハードウェア PWM は以下の表に従ってサポートされます:

| バックライトピン | AT90USB64/128 | ATmega16/32U4 | ATmega16/32U2 | ATmega32A | ATmega328/P |
|-------------|-------------|-------------|-------------|---------|----------|
| `B1`        |             |             |             |         | Timer 1  |
| `B2`        |             |             |             |         | Timer 1  |
| `B5`        | Timer 1     | Timer 1     |             |         |          |
| `B6`        | Timer 1     | Timer 1     |             |         |          |
| `B7`        | Timer 1     | Timer 1     | Timer 1     |         |          |
| `C4`        | Timer 3     |             |             |         |          |
| `C5`        | Timer 3     |             | Timer 1     |         |          |
| `C6`        | Timer 3     | Timer 3     | Timer 1     |         |          |
| `D4`        |             |             |             | Timer 1 |          |
| `D5`        |             |             |             | Timer 1 |          |

他の全てのピンはソフトウェア PWM を使います。[オーディオ](ja/feature_audio.md)機能が無効あるいは1つのタイマだけを使っている場合は、ハードウェアタイマによってバックライト PWM を引き起こすことができます:

| オーディオピン | オーディオタイマ | ソフトウェア PWM タイマ |
|---------|-----------|------------------|
| `C4`    | Timer 3 | Timer 1 |
| `C5`    | Timer 3 | Timer 1 |
| `C6`    | Timer 3 | Timer 1 |
| `B5`    | Timer 1 | Timer 3 |
| `B6`    | Timer 1 | Timer 3 |
| `B7`    | Timer 1 | Timer 3 |

両方のタイマーがオーディオのために使われている場合、バックライト PWM はハードウェアタイマを使いませんが、代わりにマトリックススキャンの間に引き起こされます。この場合、PWM の計算は十分なタイミングの精度で呼ばれないかもしれないため、バックライトの明滅はサポートされず、バックライトもちらつくかもしれません。

### AVR 設定

バックライトの挙動を変更するには、`config.h` の中で以下の `#define` をします:

| 定義 | デフォルト | 説明 |
|---------------------|-------------|--------------------------------------------------------------------------------------------------------------|
| `BACKLIGHT_PIN`       | `B7`      | LED を制御するピン。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |
| `BACKLIGHT_PINS`      | *定義なし* | 実験的: 詳細は以下を見てください |
| `BACKLIGHT_LEVELS`    | `3`       | 輝度のレベルの数 (オフを除いて最大 31) |
| `BACKLIGHT_CAPS_LOCK` | *定義なし* | バックライトを使って Caps Lock のインジケータを有効にする (専用 LED の無いキーボードのため) |
| `BACKLIGHT_BREATHING` | *定義なし* | サポートされる場合は、バックライトの明滅動作を有効にする |
| `BREATHING_PERIOD`    | `6`       | 各バックライトの "明滅" の長さ（秒） |
| `BACKLIGHT_ON_STATE`  | `1`       | バックライトが "オン" の時のバックライトピンの状態 - high の場合は `1`、low の場合は `0` |

### バックライトオン状態

ほとんどのバックライトの回路は N チャンネルの MOSFET あるいは NPN トランジスタによって駆動されます。これは、トランジスタを*オン*にして LED を点灯させるには、ゲートまたはベースに接続されているバックライトピンを *high* に駆動する必要があることを意味します。
ただし、P チャンネルの MOSFET あるいは PNP トランジスタが使われる場合があります。この場合、トランジスタがオンの時、ピンは代わりに *low* で駆動されます。

この機能は `BACKLIGHT_ON_STATE` 定義することでキーボードレベルで設定されます。

### 複数のバックライトピン

ほとんどのキーボードは、全てのバックライト LED を制御するたった1つのバックライトピンを持ちます (特にバックライトがハードウェア PWM ピンに接続されている場合)。
ソフトウェア PWM では、複数のバックライトピンを定義することができます。これらすべてのピンは PWM デューティサイクル時に同時にオンおよびオフになります。
この機能により、例えば Caps Lock LED (またはその他の制御可能な LED) の輝度を、バックライトの他の LED と同じレベルに設定することができます。Caps Lock の代わりに LCTRL をマップしていて、Caps Lock がオンの時に Caps Lock LED をアクティブにする代わりにバックライトの一部にする必要がある場合に便利です。

複数のバックライトピンをアクティブにするには、`config.h` に次のようなものを追加する必要があります:

```c
#define BACKLIGHT_LED_COUNT 2
#undef BACKLIGHT_PIN
#define BACKLIGHT_PINS { F5, B2 }
```

### ハードウェア PWM 実装

バックライト用にサポートされているピンを使う場合、QMK は PWM 信号を出力するように設定されたハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。
希望の輝度が計算され、`OCRxx` レジスタ内に格納されます。カウンタがこの値まで達すると、バックライトピンは low になり、カウンタがリセットされると再び high になります。
このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。`0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。

明滅動作の効果はカウンタがリセットされる(秒間あたりおよそ244回)たびに呼び出される `TIMER1_OVF_vect` の割り込みハンドラを登録することで可能になります。
このハンドラ内で、増分カウンタの値が事前に計算された輝度曲線にマップされます。明滅動作をオフにするには、割り込みを単純に禁止し、輝度を EEPROM に格納されているレベルに再設定します。

### タイマーにアシストされた PWM 実装

`BACKLIGHT_PIN` がハードウェアバックライトピンに設定されていない場合、QMK はソフトウェア割り込みを引き起こすように設定されているハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。
0 に再設定すると、CPU は LED をオンにする OVF (オーバーフロー)割り込みを発火し、デューティサイクルを開始します。
希望の輝度が計算され、`OCRxx` レジスタ内に格納されます。カウンタがこの値に達すると、CPU は比較出力一致割り込みを発火し、LED をオフにします。
このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。 `0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。

明滅の効果はハードウェア PWM 実装と同じです。

## ARM ドライバ

まだ初期段階ですが、ARM バックライトサポートは最終的に AVR と同等の機能を持つことを目指しています。ドライバはデフォルトで設定されますが、rules.mk 内の同等の設定は以下の通りです:
```makefile
BACKLIGHT_DRIVER = pwm
```

### 注意事項

現在のところ、ハードウェア PWM のみがサポートされ、タイマーはアシストされず、自動設定は提供されません。

?> STMF072 のバックライトサポートのテストは制限されています。人によって違うかもしれません。不明な場合は、rules.mk で `BACKLIGHT_ENABLE = no` を設定します。

### ARM 設定

バックライトの挙動を変更するには、`config.h` の中で以下の `#define` をします:

| 定義 | デフォルト | 説明 |
|------------------------|-------------|-------------------------------------------------------------------------------------------------------------|
| `BACKLIGHT_PIN`         | `B7`    | LED を制御するピン。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |
| `BACKLIGHT_PWM_DRIVER`  | `PWMD4` | 使用する PWM ドライバ。ピンから PWM タイマへのマッピングについては、ST データシートを見てください。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |
| `BACKLIGHT_PWM_CHANNEL` | `3`     | 使用する PWM チャンネル。ピンから PWM チャンネルへのマッピングについては、ST データシートを見てください。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |
| `BACKLIGHT_PAL_MODE`    | `2`     | 使用するピンの代替機能。ピンの AF マッピングについては ST データシートを見てください。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |

## Software PWM Driver :id=software-pwm-driver

他のキーボードのタスクを実行中に PWM をエミュレートすることにより、追加のプラットフォーム設定なしで最大のハードウェア互換性を提供します。トレードオフは、キーボードが忙しい時にバックライトが揺れる可能性があることです。有効にするには、rules.mk に以下を追加します:
```makefile
BACKLIGHT_DRIVER = software
```

### ソフトウェア PWM 設定

バックライトの挙動を変更するには、`config.h` の中で以下の `#define` をします:

| 定義 | デフォルト | 説明 |
|-----------------|-------------|-------------------------------------------------------------------------------------------------------------|
| `BACKLIGHT_PIN`  | `B7`      | LED を制御するピン。自身のキーボードを設計している場合を除き、これを変更する必要はないはずです |
| `BACKLIGHT_PINS` | *定義なし* | 実験的: 詳細は以下を見てください |

### 複数のバックライトピン

ほとんどのキーボードは、全てのバックライト LED を制御するたった1つのバックライトピンを持ちます (特にバックライトがハードウェア PWM ピンに接続されている場合)。
ソフトウェア PWM では、複数のバックライトピンを定義することができます。これらすべてのピンは PWM デューティサイクル時に同時にオンおよびオフになります。
この機能により、例えば Caps Lock LED (またはその他の制御可能な LED) の輝度を、バックライトの他の LED と同じレベルに設定することができます。Caps Lock の代わりに LCTRL をマップしていて、Caps Lock がオンの時に Caps Lock LED をアクティブにする代わりにバックライトの一部にする必要がある場合に便利です。

複数のバックライトピンをアクティブにするには、`config.h` に次のようなものを追加する必要があります:

```c
#undef BACKLIGHT_PIN
#define BACKLIGHT_PINS { F5, B2 }
```

## カスタムドライバ

有効にするには、rules.mk に以下を追加します:

```makefile
BACKLIGHT_DRIVER = custom
```

カスタムドライバ API を実装する場合、提供されるキーボードフックは以下の通りです:

```c
void backlight_init_ports(void) {
    // オプション - 起動時に実行されます
    //          - 通常、ここでピンを設定します
}
void backlight_set(uint8_t level) {
    // オプション - レベルの変更時に実行されます
    //          - 通常、ここで新しい値に応答します
}

void backlight_task(void) {
    // オプション - 定期的に実行されます
    //          - ここで長時間実行されるアクションはパフォーマンスの問題を引き起こします
}
```
