1
0
Fork 0

[Docs] Random Fixes (#8340)

* fix CLI section links in the Summary

* fix heading in Pointing Device doc

* fix headings in PS/2 Mouse Support doc

* add explicit section ids to I2C Master Driver doc

* reformat GPIO Controls table

Much like the I2C Master Driver doc, I found this a bit less than ideal to read. (The table was actually wider than the space available for it.)

Reformatted so each GPIO function is an H3 heading, followed by a paragraph and a table of each architecture's old-style function.

* migrate changes from I2C Master Driver doc to Japanese translation

* add explicit anchors to I2C Master Driver docs

* fix code block language markers

The language markers are case-sensitive; using the wrong case means the syntax highlighting doesn't work.

Good: ```c
Bad: ```C

* restore Japanese I2C Master Driver doc to current master

Can't update the internal tracking references accurately until the changes to the English doc are committed to master.

* add explicit anchors to edited files

* change ChibiOS/ARM to ARM/ChibiOS

Because ARM/ATSAM is also a thing that exists.

* fix code block language markers again

Used the wrong markers in a few spots. Also these are apparently always supposed to be lowercase.

* add section anchors to cli.md

* restore table formatting on GPIO Control doc

* remove changes to _summary.md
This commit is contained in:
James Young 2020-03-15 20:29:11 -07:00 committed by GitHub
parent 5f1f370463
commit b272c035ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 106 additions and 105 deletions

View file

@ -1,14 +1,14 @@
# QMK CLI # QMK CLI :id=qmk-cli
## Overview ## Overview :id=overview
The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more. The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
### Requirements ### Requirements :id=requirements
The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI. The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
### Install Using Homebrew (macOS, some Linux) ### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK: If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
@ -19,7 +19,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
``` ```
### Install Using easy_install or pip ### Install Using easy_install or pip :id=install-using-easy_install-or-pip
If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command: If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command:
@ -29,7 +29,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
``` ```
### Packaging For Other Operating Systems ### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines: We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:

View file

@ -1,10 +1,10 @@
## Pointing Device # Pointing Device :id=pointing-device
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and lightweight. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you. Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and lightweight. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
To enable Pointing Device, uncomment the following line in your rules.mk: To enable Pointing Device, uncomment the following line in your rules.mk:
``` ```makefile
POINTING_DEVICE_ENABLE = yes POINTING_DEVICE_ENABLE = yes
``` ```
@ -25,7 +25,7 @@ When the mouse report is sent, the x, y, v, and h values are set to 0 (this is d
In the following example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. Listen, this is an example: In the following example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. Listen, this is an example:
``` ```c
case MS_SPECIAL: case MS_SPECIAL:
report_mouse_t currentReport = pointing_device_get_report(); report_mouse_t currentReport = pointing_device_get_report();
if (record->event.pressed) if (record->event.pressed)

View file

@ -1,4 +1,4 @@
## PS/2 Mouse Support # PS/2 Mouse Support :id=ps2-mouse-support
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device. Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
@ -6,7 +6,7 @@ To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest fr
There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended). There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended).
### The Cirtuitry between Trackpoint and Controller ## The Circuitry between Trackpoint and Controller :id=the-circuitry-between-trackpoint-and-controller
To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+. To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+.
@ -24,20 +24,20 @@ MODULE 5+ --------+--+--------- PWR CONTROLLER
``` ```
### Busywait Version ## Busywait Version :id=busywait-version
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible. Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
In rules.mk: In rules.mk:
``` ```makefile
PS2_MOUSE_ENABLE = yes PS2_MOUSE_ENABLE = yes
PS2_USE_BUSYWAIT = yes PS2_USE_BUSYWAIT = yes
``` ```
In your keyboard config.h: In your keyboard config.h:
``` ```c
#ifdef PS2_USE_BUSYWAIT #ifdef PS2_USE_BUSYWAIT
# define PS2_CLOCK_PORT PORTD # define PS2_CLOCK_PORT PORTD
# define PS2_CLOCK_PIN PIND # define PS2_CLOCK_PIN PIND
@ -50,20 +50,20 @@ In your keyboard config.h:
#endif #endif
``` ```
### Interrupt Version ## Interrupt Version :id=interrupt-version
The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data. The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
In rules.mk: In rules.mk:
``` ```makefile
PS2_MOUSE_ENABLE = yes PS2_MOUSE_ENABLE = yes
PS2_USE_INT = yes PS2_USE_INT = yes
``` ```
In your keyboard config.h: In your keyboard config.h:
``` ```c
#ifdef PS2_USE_INT #ifdef PS2_USE_INT
#define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND #define PS2_CLOCK_PIN PIND
@ -88,20 +88,20 @@ In your keyboard config.h:
#endif #endif
``` ```
### USART Version ## USART Version :id=usart-version
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version. To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
In rules.mk: In rules.mk:
``` ```makefile
PS2_MOUSE_ENABLE = yes PS2_MOUSE_ENABLE = yes
PS2_USE_USART = yes PS2_USE_USART = yes
``` ```
In your keyboard config.h: In your keyboard config.h:
``` ```c
#ifdef PS2_USE_USART #ifdef PS2_USE_USART
#define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND #define PS2_CLOCK_PIN PIND
@ -145,13 +145,13 @@ In your keyboard config.h:
#endif #endif
``` ```
### Additional Settings ## Additional Settings :id=additional-settings
#### PS/2 Mouse Features ### PS/2 Mouse Features :id=ps2-mouse-features
These enable settings supported by the PS/2 mouse protocol. These enable settings supported by the PS/2 mouse protocol.
``` ```c
/* Use remote mode instead of the default stream mode (see link) */ /* Use remote mode instead of the default stream mode (see link) */
#define PS2_MOUSE_USE_REMOTE_MODE #define PS2_MOUSE_USE_REMOTE_MODE
@ -170,7 +170,7 @@ These enable settings supported by the PS/2 mouse protocol.
You can also call the following functions from ps2_mouse.h You can also call the following functions from ps2_mouse.h
``` ```c
void ps2_mouse_disable_data_reporting(void); void ps2_mouse_disable_data_reporting(void);
void ps2_mouse_enable_data_reporting(void); void ps2_mouse_enable_data_reporting(void);
@ -188,36 +188,36 @@ void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution);
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate); void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
``` ```
#### Fine Control ### Fine Control :id=fine-control
Use the following defines to change the sensitivity and speed of the mouse. Use the following defines to change the sensitivity and speed of the mouse.
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads). Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
``` ```c
#define PS2_MOUSE_X_MULTIPLIER 3 #define PS2_MOUSE_X_MULTIPLIER 3
#define PS2_MOUSE_Y_MULTIPLIER 3 #define PS2_MOUSE_Y_MULTIPLIER 3
#define PS2_MOUSE_V_MULTIPLIER 1 #define PS2_MOUSE_V_MULTIPLIER 1
``` ```
#### Scroll Button ### Scroll Button :id=scroll-button
If you're using a trackpoint, you will likely want to be able to use it for scrolling. If you're using a trackpoint, you will likely want to be able to use it for scrolling.
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving. It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
To enable the feature, you must set a scroll button mask as follows: To enable the feature, you must set a scroll button mask as follows:
``` ```c
#define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BUTTON_MIDDLE) /* Default */ #define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BUTTON_MIDDLE) /* Default */
``` ```
To disable the scroll button feature: To disable the scroll button feature:
``` ```c
#define PS2_MOUSE_SCROLL_BTN_MASK 0 #define PS2_MOUSE_SCROLL_BTN_MASK 0
``` ```
The available buttons are: The available buttons are:
``` ```c
#define PS2_MOUSE_BTN_LEFT 0 #define PS2_MOUSE_BTN_LEFT 0
#define PS2_MOUSE_BTN_RIGHT 1 #define PS2_MOUSE_BTN_RIGHT 1
#define PS2_MOUSE_BTN_MIDDLE 2 #define PS2_MOUSE_BTN_MIDDLE 2
@ -229,27 +229,28 @@ Once you've configured your scroll button mask, you must configure the scroll bu
This is the interval before which if the scroll buttons were released they would be sent to the host. This is the interval before which if the scroll buttons were released they would be sent to the host.
After this interval, they will cause the mouse to scroll and will not be sent. After this interval, they will cause the mouse to scroll and will not be sent.
``` ```c
#define PS2_MOUSE_SCROLL_BTN_SEND 300 /* Default */ #define PS2_MOUSE_SCROLL_BTN_SEND 300 /* Default */
``` ```
To disable sending the scroll buttons: To disable sending the scroll buttons:
```
```c
#define PS2_MOUSE_SCROLL_BTN_SEND 0 #define PS2_MOUSE_SCROLL_BTN_SEND 0
``` ```
Fine control over the scrolling is supported with the following defines: Fine control over the scrolling is supported with the following defines:
``` ```c
#define PS2_MOUSE_SCROLL_DIVISOR_H 2 #define PS2_MOUSE_SCROLL_DIVISOR_H 2
#define PS2_MOUSE_SCROLL_DIVISOR_V 2 #define PS2_MOUSE_SCROLL_DIVISOR_V 2
``` ```
#### Invert Mouse and Scroll Axes ### Invert Mouse and Scroll Axes :id=invert-mouse-and-scroll-axes
To invert the X and Y axes you can put: To invert the X and Y axes you can put:
``` ```c
#define PS2_MOUSE_INVERT_X #define PS2_MOUSE_INVERT_X
#define PS2_MOUSE_INVERT_Y #define PS2_MOUSE_INVERT_Y
``` ```
@ -258,18 +259,18 @@ into config.h.
To reverse the scroll axes you can put: To reverse the scroll axes you can put:
``` ```c
#define PS2_MOUSE_INVERT_H #define PS2_MOUSE_INVERT_H
#define PS2_MOUSE_INVERT_V #define PS2_MOUSE_INVERT_V
``` ```
into config.h. into config.h.
#### Debug Settings ### Debug Settings :id=debug-settings
To debug the mouse, add `debug_mouse = true` or enable via bootmagic. To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
``` ```c
/* To debug the mouse reports */ /* To debug the mouse reports */
#define PS2_MOUSE_DEBUG_HID #define PS2_MOUSE_DEBUG_HID
#define PS2_MOUSE_DEBUG_RAW #define PS2_MOUSE_DEBUG_RAW

View file

@ -1,22 +1,22 @@
# RGB Matrix Lighting # RGB Matrix Lighting :id=rgb-matrix-lighting
This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it. This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it.
If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead. If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead.
## Driver configuration ## Driver configuration :id=driver-configuration
--- ---
### IS31FL3731 ### IS31FL3731 :id=is31fl3731
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
```C ```makefile
RGB_MATRIX_ENABLE = IS31FL3731 RGB_MATRIX_ENABLE = IS31FL3731
``` ```
Configure the hardware via your `config.h`: Configure the hardware via your `config.h`:
```C ```c
// This is a 7-bit address, that gets left-shifted and bit 0 // This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol) // set to 0 for write, 1 for read (as per I2C protocol)
// The address will vary depending on your wiring: // The address will vary depending on your wiring:
@ -39,7 +39,7 @@ Currently only 2 drivers are supported, but it would be trivial to support all 4
Define these arrays listing all the LEDs in your `<keyboard>.c`: Define these arrays listing all the LEDs in your `<keyboard>.c`:
```C ```c
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations /* Refer to IS31 manual for these locations
* driver * driver
@ -55,19 +55,19 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now). Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
--- ---
### IS31FL3733/IS31FL3737 ### IS31FL3733/IS31FL3737 :id=is31fl3733is31fl3737
!> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`. !> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`.
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`: There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
```C ```makefile
RGB_MATRIX_ENABLE = IS31FL3733 RGB_MATRIX_ENABLE = IS31FL3733
``` ```
Configure the hardware via your `config.h`: Configure the hardware via your `config.h`:
```C ```c
// This is a 7-bit address, that gets left-shifted and bit 0 // This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol) // set to 0 for write, 1 for read (as per I2C protocol)
// The address will vary depending on your wiring: // The address will vary depending on your wiring:
@ -90,7 +90,7 @@ Currently only a single drivers is supported, but it would be trivial to support
Define these arrays listing all the LEDs in your `<keyboard>.c`: Define these arrays listing all the LEDs in your `<keyboard>.c`:
```C ```c
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations /* Refer to IS31 manual for these locations
* driver * driver
@ -107,17 +107,17 @@ Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](
--- ---
### WS2812 ### WS2812 :id=ws2812
There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`: There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`:
```C ```makefile
RGB_MATRIX_ENABLE = WS2812 RGB_MATRIX_ENABLE = WS2812
``` ```
Configure the hardware via your `config.h`: Configure the hardware via your `config.h`:
```C ```c
// The pin connected to the data pin of the LEDs // The pin connected to the data pin of the LEDs
#define RGB_DI_PIN D7 #define RGB_DI_PIN D7
// The number of LEDs connected // The number of LEDs connected
@ -128,7 +128,7 @@ Configure the hardware via your `config.h`:
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example: From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
```C ```c
const led_config_t g_led_config = { { const led_config_t g_led_config = { {
// Key Matrix to LED Index // Key Matrix to LED Index
{ 5, NO_LED, NO_LED, 0 }, { 5, NO_LED, NO_LED, 0 },
@ -146,7 +146,7 @@ const led_config_t g_led_config = { {
The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position: The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position:
```C ```c
x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION
y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION
``` ```
@ -157,7 +157,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type. `// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
## Flags ## Flags :id=flags
|Define |Description | |Define |Description |
|------------------------------------|-------------------------------------------| |------------------------------------|-------------------------------------------|
@ -169,7 +169,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|`#define LED_FLAG_UNDERGLOW 0x02` |If the LED is for underglow. | |`#define LED_FLAG_UNDERGLOW 0x02` |If the LED is for underglow. |
|`#define LED_FLAG_KEYLIGHT 0x04` |If the LED is for key backlight. | |`#define LED_FLAG_KEYLIGHT 0x04` |If the LED is for key backlight. |
## Keycodes ## Keycodes :id=keycodes
All RGB keycodes are currently shared with the RGBLIGHT system: All RGB keycodes are currently shared with the RGBLIGHT system:
@ -189,11 +189,11 @@ All RGB keycodes are currently shared with the RGBLIGHT system:
* `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system * `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system
## RGB Matrix Effects ## RGB Matrix Effects :id=rgb-matrix-effects
All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available: All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available:
```C ```c
enum rgb_matrix_effects { enum rgb_matrix_effects {
RGB_MATRIX_NONE = 0, RGB_MATRIX_NONE = 0,
RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support
@ -285,7 +285,7 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Disables `RGB_MATRIX_SOLID_MULTISPLASH` | |`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Disables `RGB_MATRIX_SOLID_MULTISPLASH` |
## Custom RGB Matrix Effects ## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files. By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.
@ -294,7 +294,7 @@ To declare new effects, create a new `rgb_matrix_user/kb.inc` that looks somethi
`rgb_matrix_user.inc` should go in the root of the keymap directory. `rgb_matrix_user.inc` should go in the root of the keymap directory.
`rgb_matrix_kb.inc` should go in the root of the keyboard directory. `rgb_matrix_kb.inc` should go in the root of the keyboard directory.
```C ```c
// !!! DO NOT ADD #pragma once !!! // // !!! DO NOT ADD #pragma once !!! //
// Step 1. // Step 1.
@ -341,7 +341,7 @@ static bool my_cool_effect2(effect_params_t* params) {
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/` For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/`
## Colors ## Colors :id=colors
These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
@ -369,9 +369,9 @@ These are shorthands to popular colors. The `RGB` ones can be passed to the `set
These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list! These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list!
## Additional `config.h` Options ## Additional `config.h` Options :id=additional-configh-options
```C ```c
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses #define RGB_MATRIX_KEYPRESSES // reacts to keypresses
#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) #define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects #define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
@ -386,21 +386,21 @@ These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blo
#define RGB_MATRIX_STARTUP_SPD 127 // Sets the default animation speed, if none has been set #define RGB_MATRIX_STARTUP_SPD 127 // Sets the default animation speed, if none has been set
``` ```
## EEPROM storage ## EEPROM storage :id=eeprom-storage
The EEPROM for it is currently shared with the RGBLIGHT system (it's generally assumed only one RGB would be used at a time), but could be configured to use its own 32bit address with: The EEPROM for it is currently shared with the RGBLIGHT system (it's generally assumed only one RGB would be used at a time), but could be configured to use its own 32bit address with:
```C ```c
#define EECONFIG_RGB_MATRIX (uint32_t *)28 #define EECONFIG_RGB_MATRIX (uint32_t *)28
``` ```
Where `28` is an unused index from `eeconfig.h`. Where `28` is an unused index from `eeconfig.h`.
## Suspended state ## Suspended state :id=suspended-state
To use the suspend feature, add this to your `<keyboard>.c`: To use the suspend feature, add this to your `<keyboard>.c`:
```C ```c
void suspend_power_down_kb(void) void suspend_power_down_kb(void)
{ {
rgb_matrix_set_suspend_state(true); rgb_matrix_set_suspend_state(true);

View file

@ -1,16 +1,16 @@
# Stenography in QMK # Stenography in QMK :id=stenography-in-qmk
[Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy). [Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy).
The [Open Steno Project](http://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports The [Open Steno Project](http://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports
## Plover with QWERTY Keyboard ## Plover with QWERTY Keyboard :id=plover-with-qwerty-keyboard
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar. Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys. To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
## Plover with Steno Protocol ## Plover with Steno Protocol :id=plover-with-steno-protocol
Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`. Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
@ -20,26 +20,26 @@ In this mode Plover expects to speak with a steno machine over a serial port so
> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time. > Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
### TX Bolt ### TX Bolt :id=tx-bolt
TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets. TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
### GeminiPR ### GeminiPR :id=geminipr
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories. GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
## Configuring QMK for Steno ## Configuring QMK for Steno :id=configuring-qmk-for-steno
Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them. Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
```Makefile ```makefile
STENO_ENABLE = yes STENO_ENABLE = yes
MOUSEKEY_ENABLE = no MOUSEKEY_ENABLE = no
``` ```
In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function: In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
```C ```c
void matrix_init_user() { void matrix_init_user() {
steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
} }
@ -49,37 +49,37 @@ Once you have your keyboard flashed launch Plover. Click the 'Configure...' butt
On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno! On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
## Learning Stenography ## Learning Stenography :id=learning-stenography
* [Learn Plover!](https://sites.google.com/site/learnplover/) * [Learn Plover!](https://sites.google.com/site/learnplover/)
* [QWERTY Steno](http://qwertysteno.com/Home/) * [QWERTY Steno](http://qwertysteno.com/Home/)
* [Steno Jig](https://joshuagrams.github.io/steno-jig/) * [Steno Jig](https://joshuagrams.github.io/steno-jig/)
* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki * More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki
## Interfacing with the code ## Interfacing with the code :id=interfacing-with-the-code
The steno code has three interceptible hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things. The steno code has three interceptible hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things.
```C ```c
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]); bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]);
``` ```
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen. This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
```C ```c
bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
``` ```
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values. This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
```C ```c
bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed); bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
``` ```
This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys. This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys.
## Keycode Reference ## Keycode Reference :id=keycode-reference
As defined in `keymap_steno.h`. As defined in `keymap_steno.h`.

View file

@ -1,8 +1,8 @@
# I2C Master Driver # I2C Master Driver :id=i2c-master-driver
The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs. The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
## An important note on I2C Addresses ## An important note on I2C Addresses :id=note-on-i2c-addresses
All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed
@ -15,7 +15,7 @@ You can either do this on each call to the functions below, or once in your defi
See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details. See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
## Available functions ## Available functions :id=available-functions
|Function |Description | |Function |Description |
|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@ -27,7 +27,7 @@ See https://www.robot-electronics.co.uk/i2c-tutorial for more information about
|`i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read. | |`i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read. |
|`i2c_status_t i2c_stop(void);` |Ends an I2C transaction. | |`i2c_status_t i2c_stop(void);` |Ends an I2C transaction. |
### Function Return ### Function Return :id=function-return
All the above functions, except `void i2c_init(void);` return the following truth table: All the above functions, except `void i2c_init(void);` return the following truth table:
@ -38,9 +38,9 @@ All the above functions, except `void i2c_init(void);` return the following trut
|`I2C_STATUS_TIMEOUT`|-2 |Operation timed out. | |`I2C_STATUS_TIMEOUT`|-2 |Operation timed out. |
## AVR ## AVR :id=avr
### Configuration ### Configuration :id=avr-configuration
The following defines can be used to configure the I2C master driver. The following defines can be used to configure the I2C master driver.
@ -50,12 +50,12 @@ The following defines can be used to configure the I2C master driver.
AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required. AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required.
## ARM ## ARM :id=arm
For ARM the Chibios I2C HAL driver is under the hood. For ARM the Chibios I2C HAL driver is under the hood.
This section assumes an STM32 MCU. This section assumes an STM32 MCU.
### Configuration ### Configuration :id=arm-configuration
The configuration for ARM MCUs can be quite complex as often there are multiple I2C drivers which can be assigned to a variety of ports. The configuration for ARM MCUs can be quite complex as often there are multiple I2C drivers which can be assigned to a variety of ports.
@ -90,7 +90,7 @@ The ChibiOS I2C driver configuration depends on STM32 MCU:
STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1; STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1;
STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2; STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2;
#### I2Cv1 #### I2Cv1 :id=i2cv1
STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using <https://www.playembedded.org/blog/stm32-i2c-chibios/#I2Cv1_configuration_structure> as a reference: STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using <https://www.playembedded.org/blog/stm32-i2c-chibios/#I2Cv1_configuration_structure> as a reference:
| Variable | Default | | Variable | Default |
@ -99,7 +99,7 @@ STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1.
| `I2C1_CLOCK_SPEED` | `100000` | | `I2C1_CLOCK_SPEED` | `100000` |
| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` | | `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` |
#### I2Cv2 #### I2Cv2 :id=i2cv2
STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using <https://www.st.com/en/embedded-software/stsw-stm32126.html> as a reference: STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using <https://www.st.com/en/embedded-software/stsw-stm32126.html> as a reference:
| Variable | Default | | Variable | Default |
@ -117,10 +117,10 @@ STM32 MCUs allow for different "alternate function" modes when configuring GPIO
| `I2C1_SCL_PAL_MODE` | `4` | | `I2C1_SCL_PAL_MODE` | `4` |
| `I2C1_SDA_PAL_MODE` | `4` | | `I2C1_SDA_PAL_MODE` | `4` |
#### Other #### Other :id=other
You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function: You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function:
```C ```c
void i2c_init(void) void i2c_init(void)
{ {
setPinInput(B6); // Try releasing special pins for a short time setPinInput(B6); // Try releasing special pins for a short time

View file

@ -1,22 +1,22 @@
# GPIO Control # GPIO Control :id=gpio-control
QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms. QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms.
## Functions ## Functions :id=functions
The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`. The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples | |Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|----------------------|------------------------------------------------------------------|------------------------------------------------|-------------------------------------------------| |------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------|
|`setPinInput(pin)` |Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | | `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
|`setPinInputHigh(pin)`|Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | | `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
|`setPinInputLow(pin)` |Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | | `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
|`setPinOutput(pin)` |Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | | `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|`writePinHigh(pin)` |Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | | `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
|`writePinLow(pin)` |Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | | `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
|`writePin(pin, level)`|Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | | `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
|`readPin(pin)` |Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | | `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
## Advanced Settings ## Advanced Settings :id=advanced-settings
Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used. Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.