aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/custom_quantum_functions.md68
-rw-r--r--tmk_core/common/avr/suspend.c28
-rw-r--r--tmk_core/common/keyboard.c36
-rw-r--r--tmk_core/common/keyboard.h5
-rw-r--r--tmk_core/protocol/bluefruit/main.c15
-rw-r--r--tmk_core/protocol/chibios/main.c2
-rw-r--r--tmk_core/protocol/vusb/main.c1
7 files changed, 126 insertions, 29 deletions
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md
index d44786e2d..cc84e141f 100644
--- a/docs/custom_quantum_functions.md
+++ b/docs/custom_quantum_functions.md
@@ -165,18 +165,35 @@ In addition, it is possible to specify the brightness level of all LEDs with `er
165 165
166Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). 166Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default).
167 167
168# Matrix Initialization Code 168# Keyboard Initialization Code
169 169
170Before 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²c controllers you will need to set up that hardware before it can be used. 170There are several steps in the keyboard initialization process. Depending on what you want to do, it will influence which function you should use.
171 171
172These are the three main initialization functions, listed in the order that they're called.
172 173
173### Example `matrix_init_user()` Implementation 174* `keyboard_pre_init_*` - Happens before most anything is started. Good for hardware setup that you want running very early.
175* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet.
176* `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.
177
178!> 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.
179
180## Keyboard Pre Initialization code
181
182This runs very early during startup, even before the USB has been started.
183
184Shortly after this, the matrix is initialized.
185
186For most users, this shouldn't be used, as it's primarily for hardware oriented initialization.
187
188However, if you have hardware stuff that you need initialized, this is the best place for it (such as initializing LED pins).
189
190### Example `keyboard_pre_init_user()` Implementation
174 191
175This example, at the keyboard level, sets up B1, B2, and B3 as LED pins. 192This example, at the keyboard level, sets up B1, B2, and B3 as LED pins.
176 193
177```c 194```c
178void matrix_init_user(void) { 195void keyboard_pre_init_user(void) {
179 // Call the keymap level matrix init. 196 // Call the keyboard pre init code.
180 197
181 // Set our LED pins as output 198 // Set our LED pins as output
182 DDRB |= (1<<1); 199 DDRB |= (1<<1);
@@ -185,11 +202,47 @@ void matrix_init_user(void) {
185} 202}
186``` 203```
187 204
205### `keyboard_pre_init_*` Function Documentation
206
207* Keyboard/Revision: `void keyboard_pre_init_kb(void)`
208* Keymap: `void keyboard_pre_init_user(void)`
209
210## Matrix Initialization Code
211
212This 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.
213
214This is useful for setting up stuff that you may need elsewhere, but isn't hardware related nor is dependant on where it's started.
215
216
188### `matrix_init_*` Function Documentation 217### `matrix_init_*` Function Documentation
189 218
190* Keyboard/Revision: `void matrix_init_kb(void)` 219* Keyboard/Revision: `void matrix_init_kb(void)`
191* Keymap: `void matrix_init_user(void)` 220* Keymap: `void matrix_init_user(void)`
192 221
222
223## Keyboard Post Initialization code
224
225This 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.
226
227
228### Example `keyboard_post_init_user()` Implementation
229
230This example, running after everything else has initialized, sets up the rgb underglow configuration.
231
232```c
233void keyboard_post_init_user(void) {
234 // Call the post init code.
235 rgblight_enable_noeeprom(); // enables Rgb, without saving settings
236 rgblight_sethsv_noeeprom(180, 255, 255): // sets the color to teal/cyan without saving
237 rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // sets mode to Fast breathing without saving
238}
239```
240
241### `keyboard_post_init_*` Function Documentation
242
243* Keyboard/Revision: `void keyboard_post_init_kb(void)`
244* Keymap: `void keyboard_post_init_user(void)`
245
193# Matrix Scanning Code 246# Matrix Scanning Code
194 247
195Whenever 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. 248Whenever 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.
@@ -229,10 +282,9 @@ void suspend_wakeup_init_user(void)
229{ 282{
230 rgb_matrix_set_suspend_state(false); 283 rgb_matrix_set_suspend_state(false);
231} 284}
232
233``` 285```
234 286
235### `keyboard_init_*` Function Documentation 287### Keyboard suspend/wake Function Documentation
236 288
237* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` 289* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
238* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` 290* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
@@ -285,7 +337,7 @@ Keep in mind that EEPROM has a limited number of writes. While this is very high
285 337
286* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated. 338* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
287 339
288### Example Implementation 340### Example Implementation
289 341
290This 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! 342This 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!
291 343
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 1194a040e..b29447ac4 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -142,20 +142,20 @@ static void power_down(uint8_t wdto) {
142#endif 142#endif
143 suspend_power_down_kb(); 143 suspend_power_down_kb();
144 144
145 // TODO: more power saving 145 // TODO: more power saving
146 // See PicoPower application note 146 // See PicoPower application note
147 // - I/O port input with pullup 147 // - I/O port input with pullup
148 // - prescale clock 148 // - prescale clock
149 // - BOD disable 149 // - BOD disable
150 // - Power Reduction Register PRR 150 // - Power Reduction Register PRR
151 set_sleep_mode(SLEEP_MODE_PWR_DOWN); 151 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
152 sleep_enable(); 152 sleep_enable();
153 sei(); 153 sei();
154 sleep_cpu(); 154 sleep_cpu();
155 sleep_disable(); 155 sleep_disable();
156 156
157 // Disable watchdog after sleep 157 // Disable watchdog after sleep
158 wdt_disable(); 158 wdt_disable();
159} 159}
160#endif 160#endif
161 161
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 6f659b244..15652276b 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -139,6 +139,40 @@ __attribute__ ((weak))
139void matrix_setup(void) { 139void matrix_setup(void) {
140} 140}
141 141
142/** \brief keyboard_pre_init_user
143 *
144 * FIXME: needs doc
145 */
146__attribute__ ((weak))
147void keyboard_pre_init_user(void) { }
148
149/** \brief keyboard_pre_init_kb
150 *
151 * FIXME: needs doc
152 */
153__attribute__ ((weak))
154void keyboard_pre_init_kb(void) {
155 keyboard_pre_init_user();
156}
157
158/** \brief keyboard_post_init_user
159 *
160 * FIXME: needs doc
161 */
162
163__attribute__ ((weak))
164void keyboard_post_init_user() {}
165
166/** \brief keyboard_post_init_kb
167 *
168 * FIXME: needs doc
169 */
170
171__attribute__ ((weak))
172void keyboard_post_init_kb(void) {
173 keyboard_post_init_user();
174}
175
142/** \brief keyboard_setup 176/** \brief keyboard_setup
143 * 177 *
144 * FIXME: needs doc 178 * FIXME: needs doc
@@ -146,6 +180,7 @@ void matrix_setup(void) {
146void keyboard_setup(void) { 180void keyboard_setup(void) {
147 disable_jtag(); 181 disable_jtag();
148 matrix_setup(); 182 matrix_setup();
183 keyboard_pre_init_kb();
149} 184}
150 185
151/** \brief is_keyboard_master 186/** \brief is_keyboard_master
@@ -199,6 +234,7 @@ void keyboard_init(void) {
199#if defined(NKRO_ENABLE) && defined(FORCE_NKRO) 234#if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
200 keymap_config.nkro = 1; 235 keymap_config.nkro = 1;
201#endif 236#endif
237 keyboard_post_init_kb(); /* Always keep this last */
202} 238}
203 239
204/** \brief Keyboard task: Do keyboard routine jobs 240/** \brief Keyboard task: Do keyboard routine jobs
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index ea2f336e9..bf8b71fb7 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -70,6 +70,11 @@ void keyboard_set_leds(uint8_t leds);
70/* it runs whenever code has to behave differently on a slave */ 70/* it runs whenever code has to behave differently on a slave */
71bool is_keyboard_master(void); 71bool is_keyboard_master(void);
72 72
73void keyboard_pre_init_kb(void);
74void keyboard_pre_init_user(void);
75void keyboard_post_init_kb(void);
76void keyboard_post_init_user(void);
77
73#ifdef __cplusplus 78#ifdef __cplusplus
74} 79}
75#endif 80#endif
diff --git a/tmk_core/protocol/bluefruit/main.c b/tmk_core/protocol/bluefruit/main.c
index 0dbb637e2..8a6386b4e 100644
--- a/tmk_core/protocol/bluefruit/main.c
+++ b/tmk_core/protocol/bluefruit/main.c
@@ -42,13 +42,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
42 42
43 43
44int main(void) 44int main(void)
45{ 45{
46 46
47 CPU_PRESCALE(0); 47 CPU_PRESCALE(0);
48 48
49 // DDRD = _BV(PD5); 49 // DDRD = _BV(PD5);
50 // DDRB = _BV(PB0); 50 // DDRB = _BV(PB0);
51 51
52 // PORTD = _BV(PD5); 52 // PORTD = _BV(PD5);
53 // PORTB = _BV(PB0); 53 // PORTB = _BV(PB0);
54 54
@@ -59,22 +59,23 @@ int main(void)
59 // while (!usb_configured()) /* wait */ 59 // while (!usb_configured()) /* wait */
60 60
61 61
62 keyboard_setup();
62 63
63 dprintf("Initializing keyboard...\n"); 64 dprintf("Initializing keyboard...\n");
64 keyboard_init(); 65 keyboard_init();
65 66
66 // This implementation is pretty simplistic... if the USB connection 67 // This implementation is pretty simplistic... if the USB connection
67 // is not configured, choose the Bluefruit, otherwise use USB 68 // is not configured, choose the Bluefruit, otherwise use USB
68 // Definitely would prefer to have this driven by an input pin and make 69 // Definitely would prefer to have this driven by an input pin and make
69 // it switch dynamically - BCG 70 // it switch dynamically - BCG
70 // if (!usb_configured()) { 71 // if (!usb_configured()) {
71 72
72 // // Send power to Bluefruit... Adafruit says it takes 27 mA, I think 73 // // Send power to Bluefruit... Adafruit says it takes 27 mA, I think
73 // // the pins should provide 40 mA, but just in case I switch the 74 // // the pins should provide 40 mA, but just in case I switch the
74 // // Bluefruit using a transistor - BCG 75 // // Bluefruit using a transistor - BCG
75 // DDRB = _BV(PB6); 76 // DDRB = _BV(PB6);
76 // PORTB |= _BV(PB6); 77 // PORTB |= _BV(PB6);
77 78
78 dprintf("Setting host driver to bluefruit...\n"); 79 dprintf("Setting host driver to bluefruit...\n");
79 host_set_driver(bluefruit_driver()); 80 host_set_driver(bluefruit_driver());
80 81
@@ -131,7 +132,7 @@ int main(void)
131// usb_remote_wakeup(); 132// usb_remote_wakeup();
132// } 133// }
133// } 134// }
134// keyboard_task(); 135// keyboard_task();
135// } 136// }
136// } 137// }
137 138
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 5436d4909..8de55bfe3 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -119,6 +119,8 @@ int main(void) {
119 // TESTING 119 // TESTING
120 // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); 120 // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
121 121
122 keyboard_setup();
123
122 /* Init USB */ 124 /* Init USB */
123 init_usb_driver(&USB_DRIVER); 125 init_usb_driver(&USB_DRIVER);
124 126
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index f6a0c7e9a..86c2188c8 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -56,6 +56,7 @@ int main(void)
56#ifndef NO_UART 56#ifndef NO_UART
57 uart_init(UART_BAUD_RATE); 57 uart_init(UART_BAUD_RATE);
58#endif 58#endif
59 keyboard_setup();
59 60
60 keyboard_init(); 61 keyboard_init();
61 host_set_driver(vusb_driver()); 62 host_set_driver(vusb_driver());