diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/cli.md | 12 | ||||
-rw-r--r-- | docs/feature_pointing_device.md | 6 | ||||
-rw-r--r-- | docs/feature_ps2_mouse.md | 59 | ||||
-rw-r--r-- | docs/feature_rgb_matrix.md | 56 | ||||
-rw-r--r-- | docs/feature_stenography.md | 28 | ||||
-rw-r--r-- | docs/i2c_driver.md | 24 | ||||
-rw-r--r-- | docs/internals_gpio_control.md | 26 |
7 files changed, 106 insertions, 105 deletions
diff --git a/docs/cli.md b/docs/cli.md index 165f2a372..760fe1cdb 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -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. -### 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. -### 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: @@ -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 ``` -### 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: @@ -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 ``` -### 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: diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index 8ad428939..b90c341d5 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -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. To enable Pointing Device, uncomment the following line in your rules.mk: -``` +```makefile 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: -``` +```c case MS_SPECIAL: report_mouse_t currentReport = pointing_device_get_report(); if (record->event.pressed) diff --git a/docs/feature_ps2_mouse.md b/docs/feature_ps2_mouse.md index d13896799..ce072fbe9 100644 --- a/docs/feature_ps2_mouse.md +++ b/docs/feature_ps2_mouse.md @@ -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. @@ -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). -### 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+. @@ -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. In rules.mk: -``` +```makefile PS2_MOUSE_ENABLE = yes PS2_USE_BUSYWAIT = yes ``` In your keyboard config.h: -``` +```c #ifdef PS2_USE_BUSYWAIT # define PS2_CLOCK_PORT PORTD # define PS2_CLOCK_PIN PIND @@ -50,20 +50,20 @@ In your keyboard config.h: #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. In rules.mk: -``` +```makefile PS2_MOUSE_ENABLE = yes PS2_USE_INT = yes ``` In your keyboard config.h: -``` +```c #ifdef PS2_USE_INT #define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PIN PIND @@ -88,20 +88,20 @@ In your keyboard config.h: #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. In rules.mk: -``` +```makefile PS2_MOUSE_ENABLE = yes PS2_USE_USART = yes ``` In your keyboard config.h: -``` +```c #ifdef PS2_USE_USART #define PS2_CLOCK_PORT PORTD #define PS2_CLOCK_PIN PIND @@ -145,13 +145,13 @@ In your keyboard config.h: #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. -``` +```c /* Use remote mode instead of the default stream mode (see link) */ #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 -``` +```c void ps2_mouse_disable_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); ``` -#### Fine Control +### Fine Control :id=fine-control 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). -``` +```c #define PS2_MOUSE_X_MULTIPLIER 3 #define PS2_MOUSE_Y_MULTIPLIER 3 #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. 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: -``` +```c #define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BUTTON_MIDDLE) /* Default */ ``` To disable the scroll button feature: -``` +```c #define PS2_MOUSE_SCROLL_BTN_MASK 0 ``` The available buttons are: -``` +```c #define PS2_MOUSE_BTN_LEFT 0 #define PS2_MOUSE_BTN_RIGHT 1 #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. After this interval, they will cause the mouse to scroll and will not be sent. -``` +```c #define PS2_MOUSE_SCROLL_BTN_SEND 300 /* Default */ ``` To disable sending the scroll buttons: -``` + +```c #define PS2_MOUSE_SCROLL_BTN_SEND 0 ``` Fine control over the scrolling is supported with the following defines: -``` +```c #define PS2_MOUSE_SCROLL_DIVISOR_H 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: -``` +```c #define PS2_MOUSE_INVERT_X #define PS2_MOUSE_INVERT_Y ``` @@ -258,18 +259,18 @@ into config.h. To reverse the scroll axes you can put: -``` +```c #define PS2_MOUSE_INVERT_H #define PS2_MOUSE_INVERT_V ``` into config.h. -#### Debug Settings +### Debug Settings :id=debug-settings To debug the mouse, add `debug_mouse = true` or enable via bootmagic. -``` +```c /* To debug the mouse reports */ #define PS2_MOUSE_DEBUG_HID #define PS2_MOUSE_DEBUG_RAW diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 23082ef2a..7bc219347 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -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. 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`: -```C +```makefile RGB_MATRIX_ENABLE = IS31FL3731 ``` Configure the hardware via your `config.h`: -```C +```c // This is a 7-bit address, that gets left-shifted and bit 0 // set to 0 for write, 1 for read (as per I2C protocol) // The address will vary depending on your wiring: @@ -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`: -```C +```c const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * 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). --- -### IS31FL3733/IS31FL3737 +### IS31FL3733/IS31FL3737 :id=is31fl3733is31fl3737 !> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`. There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`: -```C +```makefile RGB_MATRIX_ENABLE = IS31FL3733 ``` Configure the hardware via your `config.h`: -```C +```c // This is a 7-bit address, that gets left-shifted and bit 0 // set to 0 for write, 1 for read (as per I2C protocol) // The address will vary depending on your wiring: @@ -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`: -```C +```c const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * 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`: -```C +```makefile RGB_MATRIX_ENABLE = WS2812 ``` Configure the hardware via your `config.h`: -```C +```c // The pin connected to the data pin of the LEDs #define RGB_DI_PIN D7 // 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: -```C +```c const led_config_t g_led_config = { { // Key Matrix to LED Index { 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: -```C +```c x = 224 / (NUMBER_OF_COLS - 1) * COL_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. -## Flags +## Flags :id=flags |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_KEYLIGHT 0x04` |If the LED is for key backlight. | -## Keycodes +## Keycodes :id=keycodes 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 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: -```C +```c enum rgb_matrix_effects { RGB_MATRIX_NONE = 0, 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` | -## 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. @@ -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_kb.inc` should go in the root of the keyboard directory. -```C +```c // !!! DO NOT ADD #pragma once !!! // // 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/` -## 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. @@ -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! -## Additional `config.h` Options +## Additional `config.h` Options :id=additional-configh-options -```C +```c #define RGB_MATRIX_KEYPRESSES // reacts to 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 @@ -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 ``` -## 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: -```C +```c #define EECONFIG_RGB_MATRIX (uint32_t *)28 ``` 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`: -```C +```c void suspend_power_down_kb(void) { rgb_matrix_set_suspend_state(true); diff --git a/docs/feature_stenography.md b/docs/feature_stenography.md index 4d7374a03..099993f85 100644 --- a/docs/feature_stenography.md +++ b/docs/feature_stenography.md @@ -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). 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. 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`. @@ -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. -### 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. -### 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. -## 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. -```Makefile +```makefile STENO_ENABLE = yes MOUSEKEY_ENABLE = no ``` In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function: -```C +```c void matrix_init_user() { 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! -## Learning Stenography +## Learning Stenography :id=learning-stenography * [Learn Plover!](https://sites.google.com/site/learnplover/) * [QWERTY Steno](http://qwertysteno.com/Home/) * [Steno Jig](https://joshuagrams.github.io/steno-jig/) * More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki -## Interfacing with the code +## 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. -```C +```c bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]); ``` This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen. -```C +```c bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } ``` This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values. -```C +```c bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed); ``` This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys. -## Keycode Reference +## Keycode Reference :id=keycode-reference As defined in `keymap_steno.h`. diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md index c9f53ef0d..d28a20fa1 100644 --- a/docs/i2c_driver.md +++ b/docs/i2c_driver.md @@ -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. -## 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 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. -## Available functions +## Available functions :id=available-functions |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_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: @@ -38,9 +38,9 @@ All the above functions, except `void i2c_init(void);` return the following trut |`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. @@ -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. -## ARM +## ARM :id=arm For ARM the Chibios I2C HAL driver is under the hood. 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. @@ -90,7 +90,7 @@ The ChibiOS I2C driver configuration depends on STM32 MCU: STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1; STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2; -#### I2Cv1 +#### 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: | Variable | Default | @@ -99,7 +99,7 @@ STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. | `I2C1_CLOCK_SPEED` | `100000` | | `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: | Variable | Default | @@ -117,10 +117,10 @@ STM32 MCUs allow for different "alternate function" modes when configuring GPIO | `I2C1_SCL_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: -```C +```c void i2c_init(void) { setPinInput(B6); // Try releasing special pins for a short time diff --git a/docs/internals_gpio_control.md b/docs/internals_gpio_control.md index 8b8351382..74ac09035 100644 --- a/docs/internals_gpio_control.md +++ b/docs/internals_gpio_control.md @@ -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. -## Functions +## Functions :id=functions The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`. -|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples | -|----------------------|------------------------------------------------------------------|------------------------------------------------|-------------------------------------------------| -|`setPinInput(pin)` |Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | -|`setPinInputHigh(pin)`|Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | -|`setPinInputLow(pin)` |Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | -|`setPinOutput(pin)` |Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -|`writePinHigh(pin)` |Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | -|`writePinLow(pin)` |Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | -|`writePin(pin, level)`|Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | -|`readPin(pin)` |Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | +|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples | +|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------| +| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | +| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | +| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | +| `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | +| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | +| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | +| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | +| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | -## 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. |