]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - docs/custom_quantum_functions.md
add keyboards/mxss/rgblight.h from e661f1559:quantum/rgblight.h (#5461)
[qmk_firmware.git] / docs / custom_quantum_functions.md
index d44786e2d512855dda29b60b18e0e7b982e6cd9b..655fa1578e5724ff73d8e33cc7a005cf5982785c 100644 (file)
@@ -116,29 +116,29 @@ Use the `IS_LED_ON(usb_led, led_name)` and `IS_LED_OFF(usb_led, led_name)` macro
 ```c
 void led_set_user(uint8_t usb_led) {
     if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
-        PORTB |= (1<<0);
+        writePinLow(B0);
     } else {
-        PORTB &= ~(1<<0);
+        writePinHigh(B0);
     }
     if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
-        PORTB |= (1<<1);
+        writePinLow(B1);
     } else {
-        PORTB &= ~(1<<1);
+        writePinHigh(B1);
     }
     if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
-        PORTB |= (1<<2);
+        writePinLow(B2);
     } else {
-        PORTB &= ~(1<<2);
+        writePinHigh(B2);
     }
     if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) {
-        PORTB |= (1<<3);
+        writePinLow(B3);
     } else {
-        PORTB &= ~(1<<3);
+        writePinHigh(B3);
     }
     if (IS_LED_ON(usb_led, USB_LED_KANA)) {
-        PORTB |= (1<<4);
+        writePinLow(B4);
     } else {
-        PORTB &= ~(1<<4);
+        writePinHigh(B4);
     }
 }
 ```
@@ -165,31 +165,86 @@ In addition, it is possible to specify the brightness level of all LEDs with `er
 
 Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default).
 
-# Matrix Initialization Code
+# Keyboard Initialization Code
 
-Before a keyboard can be used the hardware must be initialized. QMK handles initialization of the keyboard matrix itself, but if you have other hardware like LEDs or i&#xb2;c controllers you will need to set up that hardware before it can be used.
+There are several steps in the keyboard initialization process.  Depending on what you want to do, it will influence which function you should use.
 
+These are the three main initialization functions, listed in the order that they're called.
 
-### Example `matrix_init_user()` Implementation
+* `keyboard_pre_init_*` - Happens before most anything is started. Good for hardware setup that you want running very early.
+* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet.
+* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part.
 
-This example, at the keyboard level, sets up B1, B2, and B3 as LED pins.
+!> For most people, the `keyboard_post_init_user` function is what you want to call.  For instance, this is where you want to set up things for RGB Underglow.
+
+## Keyboard Pre Initialization code
+
+This runs very early during startup, even before the USB has been started. 
+
+Shortly after this, the matrix is initialized.
+
+For most users, this shouldn't be used, as it's primarily for hardware oriented initialization. 
+
+However, if you have hardware stuff that you need initialized, this is the best place for it (such as initializing LED pins).
+
+### Example `keyboard_pre_init_user()` Implementation
+
+This example, at the keyboard level, sets up B0, B1, B2, B3, and B4 as LED pins.
 
 ```c
-void matrix_init_user(void) {
-  // Call the keymap level matrix init.
+void keyboard_pre_init_user(void) {
+  // Call the keyboard pre init code.
 
   // Set our LED pins as output
-  DDRB |= (1<<1);
-  DDRB |= (1<<2);
-  DDRB |= (1<<3);
+  setPinOutput(B0);
+  setPinOutput(B1);
+  setPinOutput(B2);
+  setPinOutput(B3);
+  setPinOutput(B4);
 }
 ```
 
+### `keyboard_pre_init_*` Function Documentation
+
+* Keyboard/Revision: `void keyboard_pre_init_kb(void)`
+* Keymap: `void keyboard_pre_init_user(void)`
+
+## Matrix Initialization Code
+
+This is called when the matrix is initialized, and after some of the hardware has been set up, but before many of the features have been initialized. 
+
+This is useful for setting up stuff that you may need elsewhere, but isn't hardware related nor is dependant on where it's started. 
+
+
 ### `matrix_init_*` Function Documentation
 
 * Keyboard/Revision: `void matrix_init_kb(void)`
 * Keymap: `void matrix_init_user(void)`
 
+
+## Keyboard Post Initialization code
+
+This is ran as the very last task in the keyboard initialization process. This is useful if you want to make changes to certain features, as they should be initialized by this point.
+
+
+### Example `keyboard_post_init_user()` Implementation
+
+This example, running after everything else has initialized, sets up the rgb underglow configuration.
+
+```c
+void keyboard_post_init_user(void) {
+  // Call the post init code.
+  rgblight_enable_noeeprom(); // enables Rgb, without saving settings
+  rgblight_sethsv_noeeprom(180, 255, 255): // sets the color to teal/cyan without saving
+  rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // sets mode to Fast breathing without saving
+}
+```
+
+### `keyboard_post_init_*` Function Documentation
+
+* Keyboard/Revision: `void keyboard_post_init_kb(void)`
+* Keymap: `void keyboard_post_init_user(void)`
+
 # Matrix Scanning Code
 
 Whenever possible you should customize your keyboard by using `process_record_*()` and hooking into events that way, to ensure that your code does not have a negative performance impact on your keyboard. However, in rare cases it is necessary to hook into the matrix scanning. Be extremely careful with the performance of code in these functions, as it will be called at least 10 times per second.
@@ -217,22 +272,18 @@ This is controlled by two functions: `suspend_power_down_*` and `suspend_wakeup_
 
 ### Example suspend_power_down_user() and suspend_wakeup_init_user() Implementation
 
-This example, at the keyboard level, sets up B1, B2, and B3 as LED pins.
 
 ```c
-void suspend_power_down_user(void)
-{
+void suspend_power_down_user(void) {
     rgb_matrix_set_suspend_state(true);
 }
 
-void suspend_wakeup_init_user(void)
-{
+void suspend_wakeup_init_user(void) {
     rgb_matrix_set_suspend_state(false);
 }
-
 ```
 
-### `keyboard_init_*` Function Documentation
+### Keyboard suspend/wake  Function Documentation
 
 * Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
 * Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
@@ -269,7 +320,7 @@ uint32_t layer_state_set_user(uint32_t state) {
 ```
 ### `layer_state_set_*` Function Documentation
 
-* Keyboard/Revision: `void uint32_t layer_state_set_kb(uint32_t state)`
+* Keyboard/Revision: `uint32_t layer_state_set_kb(uint32_t state)`
 * Keymap: `uint32_t layer_state_set_user(uint32_t state)`
 
 The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
@@ -285,7 +336,7 @@ Keep in mind that EEPROM has a limited number of writes. While this is very high
 
 * If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated. 
 
-### Example  Implementation
+### Example Implementation
 
 This is an example of how to add settings, and read and write it. We're using the user keymap for the example here.  This is a complex function, and has a lot going on.  In fact, it uses a lot of the above functions to work! 
 
@@ -304,11 +355,11 @@ user_config_t user_config;
 
 This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits.  You can mix and match, but changing the order can cause issues, as it will change the values that are read and written. 
 
-We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `matrix_init_user` and `process_record_user` to configure everything. 
+We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything. 
 
-Now, using the `matrix_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap.  And It should look like: 
+Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap.  And It should look like: 
 ```
-void matrix_init_user(void) {
+void keyboard_post_init_user(void) {
   // Call the keymap level matrix init.
 
   // Read the user config from EEPROM
@@ -395,6 +446,7 @@ And lastly, you want to add the `eeconfig_init_user` function, so that when the
 
 ```
 void eeconfig_init_user(void) {  // EEPROM is getting reset! 
+  user_config.raw = 0;
   user_config.rgb_layer_change = true; // We want this enabled by default
   eeconfig_update_user(user_config.raw); // Write default value to EEPROM now