aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-09-13 14:59:53 +0100
committerGitHub <noreply@github.com>2021-09-13 14:59:53 +0100
commitcb4346edb74b415928e3274d166802f5afd3004d (patch)
treead9bb2c4bfbae0686a6c56184f312a82592107f3
parent8a3f97b20fe532ee9b085e8ba407bfcc8fac3504 (diff)
downloadqmk_firmware-cb4346edb74b415928e3274d166802f5afd3004d.tar.gz
qmk_firmware-cb4346edb74b415928e3274d166802f5afd3004d.zip
Migrate hadron away from QWIIC_DRIVERS (#14415)
-rw-r--r--keyboards/hadron/i2c.c166
-rw-r--r--keyboards/hadron/i2c.h46
-rw-r--r--keyboards/hadron/ver2/config.h6
-rw-r--r--keyboards/hadron/ver2/keymaps/default/keymap.c121
-rw-r--r--keyboards/hadron/ver2/keymaps/readme.md22
-rw-r--r--keyboards/hadron/ver2/keymaps/side_numpad/keymap.c162
-rw-r--r--keyboards/hadron/ver2/rules.mk32
-rw-r--r--keyboards/hadron/ver2/ver2.c64
-rw-r--r--keyboards/hadron/ver2/ver2.h2
-rw-r--r--keyboards/hadron/ver3/config.h12
-rw-r--r--keyboards/hadron/ver3/keymaps/default/config.h1
-rw-r--r--keyboards/hadron/ver3/keymaps/default/keymap.c4
-rw-r--r--keyboards/hadron/ver3/keymaps/readme.md24
-rw-r--r--keyboards/hadron/ver3/rules.mk4
-rw-r--r--keyboards/hadron/ver3/ver3.c222
15 files changed, 155 insertions, 733 deletions
diff --git a/keyboards/hadron/i2c.c b/keyboards/hadron/i2c.c
deleted file mode 100644
index cd2b835d5..000000000
--- a/keyboards/hadron/i2c.c
+++ /dev/null
@@ -1,166 +0,0 @@
1#include <util/twi.h>
2#include <avr/io.h>
3#include <stdlib.h>
4#include <avr/interrupt.h>
5#include <util/twi.h>
6#include <stdbool.h>
7#include "i2c.h"
8
9#ifdef USE_I2C
10
11// Limits the amount of we wait for any one i2c transaction.
12// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
13// 9 bits, a single transaction will take around 90μs to complete.
14//
15// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit
16// poll loop takes at least 8 clock cycles to execute
17#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
18
19#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
20
21volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
22
23static volatile uint8_t slave_buffer_pos;
24static volatile bool slave_has_register_set = false;
25
26// Wait for an i2c operation to finish
27inline static
28void i2c_delay(void) {
29 uint16_t lim = 0;
30 while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
31 lim++;
32
33 // easier way, but will wait slightly longer
34 // _delay_us(100);
35}
36
37// Setup twi to run at 100kHz
38void i2c_master_init(void) {
39 // no prescaler
40 TWSR = 0;
41 // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
42 // Check datasheets for more info.
43 TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
44}
45
46// Start a transaction with the given i2c slave address. The direction of the
47// transfer is set with I2C_READ and I2C_WRITE.
48// returns: 0 => success
49// 1 => error
50uint8_t i2c_master_start(uint8_t address) {
51 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
52
53 i2c_delay();
54
55 // check that we started successfully
56 if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
57 return 1;
58
59 // send device address
60 TWDR = address;
61 TWCR = (1<<TWINT) | (1<<TWEN);
62
63 i2c_delay();
64
65 if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
66 return 1; // slave did not acknowledge
67 else
68 return 0; // success
69}
70
71
72// Finish the i2c transaction.
73void i2c_master_stop(void) {
74 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
75
76 uint16_t lim = 0;
77 while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
78 lim++;
79}
80
81// Write one byte to the i2c slave.
82// returns 0 => slave ACK
83// 1 => slave NACK
84uint8_t i2c_master_write(uint8_t data) {
85 TWDR = data;
86 TWCR = (1<<TWINT) | (1<<TWEN);
87
88 i2c_delay();
89
90 // check if the slave acknowledged us
91 return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
92}
93
94// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
95// if ack=0 the acknowledge bit is not set.
96// returns: byte read from i2c device
97uint8_t i2c_master_read(int ack) {
98 TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
99
100 i2c_delay();
101 return TWDR;
102}
103
104void i2c_reset_state(void) {
105 TWCR = 0;
106}
107
108void i2c_slave_init(uint8_t address) {
109 TWAR = address << 0; // slave i2c address
110 // TWEN - twi enable
111 // TWEA - enable address acknowledgement
112 // TWINT - twi interrupt flag
113 // TWIE - enable the twi interrupt
114 TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
115}
116
117ISR(TWI_vect);
118
119ISR(TWI_vect) {
120 uint8_t ack = 1;
121 switch(TW_STATUS) {
122 case TW_SR_SLA_ACK:
123 // this device has been addressed as a slave receiver
124 slave_has_register_set = false;
125 break;
126
127 case TW_SR_DATA_ACK:
128 // this device has received data as a slave receiver
129 // The first byte that we receive in this transaction sets the location
130 // of the read/write location of the slaves memory that it exposes over
131 // i2c. After that, bytes will be written at slave_buffer_pos, incrementing
132 // slave_buffer_pos after each write.
133 if(!slave_has_register_set) {
134 slave_buffer_pos = TWDR;
135 // don't acknowledge the master if this memory loctaion is out of bounds
136 if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
137 ack = 0;
138 slave_buffer_pos = 0;
139 }
140 slave_has_register_set = true;
141 } else {
142 i2c_slave_buffer[slave_buffer_pos] = TWDR;
143 BUFFER_POS_INC();
144 }
145 break;
146
147 case TW_ST_SLA_ACK:
148 case TW_ST_DATA_ACK:
149 // master has addressed this device as a slave transmitter and is
150 // requesting data.
151 TWDR = i2c_slave_buffer[slave_buffer_pos];
152 BUFFER_POS_INC();
153 break;
154
155 case TW_BUS_ERROR: // something went wrong, reset twi state
156 TWCR = 0;
157 default:
158 break;
159 }
160 // Reset everything, so we are ready for the next TWI interrupt
161 TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
162}
163
164
165
166#endif
diff --git a/keyboards/hadron/i2c.h b/keyboards/hadron/i2c.h
deleted file mode 100644
index 7ecf6eb27..000000000
--- a/keyboards/hadron/i2c.h
+++ /dev/null
@@ -1,46 +0,0 @@
1#pragma once
2
3#include <stdint.h>
4
5#ifndef F_CPU
6#define F_CPU 16000000UL
7#endif
8
9#define I2C_READ 1
10#define I2C_WRITE 0
11
12#define I2C_ACK 1
13#define I2C_NACK 0
14
15#define SLAVE_BUFFER_SIZE 0x10
16
17// i2c SCL clock frequency
18#define SCL_CLOCK 800000L
19
20extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
21
22void i2c_master_init(void);
23uint8_t i2c_master_start(uint8_t address);
24void i2c_master_stop(void);
25uint8_t i2c_master_write(uint8_t data);
26uint8_t i2c_master_read(int);
27void i2c_reset_state(void);
28void i2c_slave_init(uint8_t address);
29
30
31static inline unsigned char i2c_start_read(unsigned char addr) {
32 return i2c_master_start((addr << 1) | I2C_READ);
33}
34
35static inline unsigned char i2c_start_write(unsigned char addr) {
36 return i2c_master_start((addr << 1) | I2C_WRITE);
37}
38
39// from SSD1306 scrips
40extern unsigned char i2c_rep_start(unsigned char addr);
41extern void i2c_start_wait(unsigned char addr);
42extern unsigned char i2c_readAck(void);
43extern unsigned char i2c_readNak(void);
44extern unsigned char i2c_read(unsigned char ack);
45
46#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
diff --git a/keyboards/hadron/ver2/config.h b/keyboards/hadron/ver2/config.h
index e051db209..c992f7fe3 100644
--- a/keyboards/hadron/ver2/config.h
+++ b/keyboards/hadron/ver2/config.h
@@ -28,10 +28,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
28#define MATRIX_COL_PINS { F6, F7, D6, C7, F5, F4, F1, F0, D2, D3, D5, B3, B2, B1, B0 } 28#define MATRIX_COL_PINS { F6, F7, D6, C7, F5, F4, F1, F0, D2, D3, D5, B3, B2, B1, B0 }
29#define UNUSED_PINS 29#define UNUSED_PINS
30 30
31 31// configure oled driver for the 128x32 oled
32#define USE_I2C 32#define OLED_UPDATE_INTERVAL 33 // ~30fps
33#define SSD1306OLED
34#define OLED_ROTATE180
35 33
36/* ws2812 RGB LED*/ 34/* ws2812 RGB LED*/
37#define RGB_DI_PIN D4 35#define RGB_DI_PIN D4
diff --git a/keyboards/hadron/ver2/keymaps/default/keymap.c b/keyboards/hadron/ver2/keymaps/default/keymap.c
index 8e3d50d3d..f24239aa2 100644
--- a/keyboards/hadron/ver2/keymaps/default/keymap.c
+++ b/keyboards/hadron/ver2/keymaps/default/keymap.c
@@ -1,10 +1,4 @@
1#include QMK_KEYBOARD_H 1#include QMK_KEYBOARD_H
2#ifdef USE_I2C
3#include "i2c.h"
4#endif
5#ifdef SSD1306OLED
6#include "ssd1306.h"
7#endif
8 2
9//Following line allows macro to read current RGB settings 3//Following line allows macro to read current RGB settings
10extern rgblight_config_t rgblight_config; 4extern rgblight_config_t rgblight_config;
@@ -18,8 +12,8 @@ extern rgblight_config_t rgblight_config;
18#define _DVORAK 2 12#define _DVORAK 2
19#define _LOWER 3 13#define _LOWER 3
20#define _RAISE 4 14#define _RAISE 4
21#define _MOUSECURSOR 8 15#define _MOUSECURSOR 5
22#define _ADJUST 16 16#define _ADJUST 6
23 17
24enum preonic_keycodes { 18enum preonic_keycodes {
25 QWERTY = SAFE_RANGE, 19 QWERTY = SAFE_RANGE,
@@ -307,115 +301,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
307 return true; 301 return true;
308} 302}
309 303
310//Functions for ver2
311#ifdef KEYBOARD_hadron_ver2
312#include <LUFA/Drivers/Peripheral/TWI.h>
313void matrix_init_user(void) { 304void matrix_init_user(void) {
314 #ifdef USE_I2C 305#ifdef AUDIO_ENABLE
315 i2c_master_init(); 306 startup_user();
316 #ifdef SSD1306OLED
317 // calls code for the SSD1306 OLED
318 _delay_ms(400);
319 TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
320 iota_gfx_init(); // turns on the display
321 #endif
322 #endif
323 #ifdef AUDIO_ENABLE
324 startup_user();
325 #endif
326}
327
328
329void matrix_scan_user(void) {
330 #ifdef SSD1306OLED
331 iota_gfx_task(); // this is what updates the display continuously
332 #endif
333}
334
335void matrix_update(struct CharacterMatrix *dest,
336 const struct CharacterMatrix *source) {
337 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
338 memcpy(dest->display, source->display, sizeof(dest->display));
339 dest->dirty = true;
340 }
341}
342//assign the right code to your layers for OLED display
343#define L_BASE 0
344#define L_LOWER 8
345#define L_RAISE 16
346#define L_FNLAYER 64
347#define L_NUMLAY 128
348#define L_NLOWER 136
349#define L_NFNLAYER 192
350#define L_MOUSECURSOR 256
351#define L_ADJUST 65560
352
353void iota_gfx_task_user(void) {
354#if DEBUG_TO_SCREEN
355 if (debug_enable) {
356 return;
357 }
358#endif
359
360 struct CharacterMatrix matrix;
361
362 matrix_clear(&matrix);
363 matrix_write_P(&matrix, PSTR("USB: "));
364#ifdef PROTOCOL_LUFA
365 switch (USB_DeviceState) {
366 case DEVICE_STATE_Unattached:
367 matrix_write_P(&matrix, PSTR("Unattached"));
368 break;
369 case DEVICE_STATE_Suspended:
370 matrix_write_P(&matrix, PSTR("Suspended"));
371 break;
372 case DEVICE_STATE_Configured:
373 matrix_write_P(&matrix, PSTR("Connected"));
374 break;
375 case DEVICE_STATE_Powered:
376 matrix_write_P(&matrix, PSTR("Powered"));
377 break;
378 case DEVICE_STATE_Default:
379 matrix_write_P(&matrix, PSTR("Default"));
380 break;
381 case DEVICE_STATE_Addressed:
382 matrix_write_P(&matrix, PSTR("Addressed"));
383 break;
384 default:
385 matrix_write_P(&matrix, PSTR("Invalid"));
386 }
387#endif 307#endif
388
389// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
390
391 char buf[40];
392 snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
393 matrix_write_P(&matrix, PSTR("\n\nLayer: "));
394 switch (layer_state) {
395 case L_BASE:
396 matrix_write_P(&matrix, PSTR("Default"));
397 break;
398 case L_RAISE:
399 matrix_write_P(&matrix, PSTR("Raise"));
400 break;
401 case L_LOWER:
402 matrix_write_P(&matrix, PSTR("Lower"));
403 break;
404 case L_ADJUST:
405 matrix_write_P(&matrix, PSTR("ADJUST"));
406 break;
407 default:
408 matrix_write(&matrix, buf);
409 }
410
411 // Host Keyboard LED Status
412 char led[40];
413 snprintf(led, sizeof(led), "\n%s %s %s",
414 (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
415 (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
416 (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
417 matrix_write(&matrix, led);
418 matrix_update(&display, &matrix);
419} 308}
420
421#endif
diff --git a/keyboards/hadron/ver2/keymaps/readme.md b/keyboards/hadron/ver2/keymaps/readme.md
deleted file mode 100644
index 2f7641d18..000000000
--- a/keyboards/hadron/ver2/keymaps/readme.md
+++ /dev/null
@@ -1,22 +0,0 @@
1# How to add your own keymap
2
3Folders can be named however you'd like (will be approved upon merging), or should follow the format with a preceding `_`:
4
5 _[ISO 3166-1 alpha-2 code*]_[layout variant]_[layout name/author]
6
7\* See full list: https://en.wikipedia.org/wiki/ISO_3166-1#Officially_assigned_code_elements
8
9and contain the following files:
10
11* `keymap.c`
12* `readme.md` *recommended*
13* `config.h` *optional*, found automatically when compiling
14* `Makefile` *optional*, found automatically when compling
15
16When adding your keymap to this list, keep it organised alphabetically (select list, edit->sort lines), and use this format:
17
18 * **folder_name** description
19
20# List of Planck keymaps
21
22* **default** default Planck layout
diff --git a/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c b/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
index c63ae9385..74f95b4b7 100644
--- a/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
+++ b/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
@@ -1,15 +1,4 @@
1#include QMK_KEYBOARD_H 1#include QMK_KEYBOARD_H
2#include <LUFA/Drivers/Peripheral/TWI.h>
3#ifdef AUDIO_ENABLE
4 #include "audio.h"
5#endif
6#ifdef USE_I2C
7#include "i2c.h"
8#endif
9#ifdef SSD1306OLED
10#include "ssd1306.h"
11#endif
12extern keymap_config_t keymap_config;
13 2
14//Following line allows macro to read current RGB settings 3//Following line allows macro to read current RGB settings
15extern rgblight_config_t rgblight_config; 4extern rgblight_config_t rgblight_config;
@@ -19,12 +8,12 @@ extern rgblight_config_t rgblight_config;
19// Layer names don't all need to be of the same length, obviously, and you can also skip them 8// Layer names don't all need to be of the same length, obviously, and you can also skip them
20// entirely and just use numbers. 9// entirely and just use numbers.
21#define _QWERTY 0 10#define _QWERTY 0
22#define _LOWER 3 11#define _LOWER 1
23#define _RAISE 4 12#define _RAISE 2
24#define _FNLAYER 6 13#define _FNLAYER 3
25#define _NUMLAY 7 14#define _NUMLAY 4
26#define _MOUSECURSOR 8 15#define _MOUSECURSOR 5
27#define _ADJUST 16 16#define _ADJUST 6
28 17
29enum preonic_keycodes { 18enum preonic_keycodes {
30 QWERTY = SAFE_RANGE, 19 QWERTY = SAFE_RANGE,
@@ -41,10 +30,7 @@ enum preonic_keycodes {
41 RGBLED_DECREASE_SAT, 30 RGBLED_DECREASE_SAT,
42 RGBLED_INCREASE_VAL, 31 RGBLED_INCREASE_VAL,
43 RGBLED_DECREASE_VAL, 32 RGBLED_DECREASE_VAL,
44}; 33 DEMOMACRO,
45
46enum macro_keycodes {
47 KC_DEMOMACRO,
48}; 34};
49 35
50// Custom macros 36// Custom macros
@@ -57,7 +43,6 @@ enum macro_keycodes {
57#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor 43#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
58#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise 44#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
59#define TG_NUMLAY TG(_NUMLAY) //Toggle for layer _NUMLAY 45#define TG_NUMLAY TG(_NUMLAY) //Toggle for layer _NUMLAY
60#define DEMOMACRO M(KC_DEMOMACRO) // My login macros
61 46
62 47
63const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 48const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -322,29 +307,20 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
322 } 307 }
323 return false; 308 return false;
324 break; 309 break;
310 case DEMOMACRO:
311 if (record->event.pressed) {
312 SEND_STRING("hello world");
313 }
314 return false;
315 break;
325 } 316 }
326 return true; 317 return true;
327} 318}
328 319
329void matrix_init_user(void) { 320void matrix_init_user(void) {
330 #ifdef USE_I2C 321#ifdef AUDIO_ENABLE
331 i2c_master_init(); 322 startup_user();
332 #ifdef SSD1306OLED 323#endif
333 // calls code for the SSD1306 OLED
334 _delay_ms(400);
335 TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
336 iota_gfx_init(); // turns on the display
337 #endif
338 #endif
339 #ifdef AUDIO_ENABLE
340 startup_user();
341 #endif
342}
343
344void matrix_scan_user(void) {
345 #ifdef SSD1306OLED
346 iota_gfx_task(); // this is what updates the display continuously
347 #endif
348} 324}
349 325
350#ifdef AUDIO_ENABLE 326#ifdef AUDIO_ENABLE
@@ -373,109 +349,3 @@ void music_scale_user(void)
373} 349}
374 350
375#endif 351#endif
376
377/*
378 * Macro definition
379 */
380const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
381{
382 if (!eeconfig_is_enabled()) {
383 eeconfig_init();
384 }
385
386 switch (id) {
387 case KC_DEMOMACRO:
388 if (record->event.pressed){
389 return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
390 }
391 }
392
393 return MACRO_NONE;
394}
395
396void matrix_update(struct CharacterMatrix *dest,
397 const struct CharacterMatrix *source) {
398 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
399 memcpy(dest->display, source->display, sizeof(dest->display));
400 dest->dirty = true;
401 }
402}
403
404//assign the right code to your layers for OLED display
405#define L_BASE 0
406#define L_LOWER 8
407#define L_RAISE 16
408#define L_FNLAYER 64
409#define L_NUMLAY 128
410#define L_NLOWER 136
411#define L_NFNLAYER 192
412#define L_MOUSECURSOR 256
413#define L_ADJUST 65560
414
415void iota_gfx_task_user(void) {
416#if DEBUG_TO_SCREEN
417 if (debug_enable) {
418 return;
419 }
420#endif
421
422 struct CharacterMatrix matrix;
423
424 matrix_clear(&matrix);
425 matrix_write_P(&matrix, PSTR("USB: "));
426#ifdef PROTOCOL_LUFA
427 switch (USB_DeviceState) {
428 case DEVICE_STATE_Unattached:
429 matrix_write_P(&matrix, PSTR("Unattached"));
430 break;
431 case DEVICE_STATE_Suspended:
432 matrix_write_P(&matrix, PSTR("Suspended"));
433 break;
434 case DEVICE_STATE_Configured:
435 matrix_write_P(&matrix, PSTR("Connected"));
436 break;
437 case DEVICE_STATE_Powered:
438 matrix_write_P(&matrix, PSTR("Powered"));
439 break;
440 case DEVICE_STATE_Default:
441 matrix_write_P(&matrix, PSTR("Default"));
442 break;
443 case DEVICE_STATE_Addressed:
444 matrix_write_P(&matrix, PSTR("Addressed"));
445 break;
446 default:
447 matrix_write_P(&matrix, PSTR("Invalid"));
448 }
449#endif
450
451// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
452
453 char buf[40];
454 snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
455 matrix_write_P(&matrix, PSTR("\n\nLayer: "));
456 switch (layer_state) {
457 case L_BASE:
458 matrix_write_P(&matrix, PSTR("Default"));
459 break;
460 case L_RAISE:
461 matrix_write_P(&matrix, PSTR("Raise"));
462 break;
463 case L_LOWER:
464 matrix_write_P(&matrix, PSTR("Lower"));
465 break;
466 case L_ADJUST:
467 matrix_write_P(&matrix, PSTR("ADJUST"));
468 break;
469 default:
470 matrix_write(&matrix, buf);
471 }
472
473 // Host Keyboard LED Status
474 char led[40];
475 snprintf(led, sizeof(led), "\n%s %s %s",
476 (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
477 (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
478 (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
479 matrix_write(&matrix, led);
480 matrix_update(&display, &matrix);
481}
diff --git a/keyboards/hadron/ver2/rules.mk b/keyboards/hadron/ver2/rules.mk
index f2ec0e7b3..79e5cccb5 100644
--- a/keyboards/hadron/ver2/rules.mk
+++ b/keyboards/hadron/ver2/rules.mk
@@ -5,27 +5,19 @@ MCU = atmega32u4
5BOOTLOADER = halfkay 5BOOTLOADER = halfkay
6 6
7# Build Options 7# Build Options
8# change to "no" to disable the options, or define them in the Makefile in 8# comment out to disable the options.
9# the appropriate keymap folder that will get included automatically
10# 9#
11BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite 10BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
12MOUSEKEY_ENABLE = no # Mouse keys 11MOUSEKEY_ENABLE = yes # Mouse keys
13EXTRAKEY_ENABLE = yes # Audio control and System control 12EXTRAKEY_ENABLE = yes # Audio control and System control
14CONSOLE_ENABLE = no # Console for debug 13CONSOLE_ENABLE = no # Console for debug
15COMMAND_ENABLE = no # Commands for debug and configuration 14COMMAND_ENABLE = no # Commands for debug and configuration
16NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
17BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
18AUDIO_ENABLE = no # Audio output on port C6
19UNICODE_ENABLE = no # Unicode
20RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
21SWAP_HANDS_ENABLE = no # Enable one-hand typing
22
23# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE 15# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
24SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 16SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
25 17# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
26 18NKRO_ENABLE = yes # USB Nkey Rollover
27EXTRAFLAGS += -flto 19BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
28 20AUDIO_ENABLE = no # Audio output
29 21RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight
30SRC = i2c.c \ 22OLED_ENABLE = yes
31 ssd1306.c 23OLED_DRIVER = SSD1306
diff --git a/keyboards/hadron/ver2/ver2.c b/keyboards/hadron/ver2/ver2.c
index f00b4f26d..ca1342749 100644
--- a/keyboards/hadron/ver2/ver2.c
+++ b/keyboards/hadron/ver2/ver2.c
@@ -1 +1,65 @@
1#include "ver2.h" 1#include "ver2.h"
2
3#ifdef OLED_ENABLE
4__attribute__ ((weak))
5oled_rotation_t oled_init_user(oled_rotation_t rotation) {
6 return OLED_ROTATION_180;
7}
8
9__attribute__ ((weak))
10void oled_task_user(void) {
11 oled_write_P(PSTR("LAYER "), false);
12 oled_write_char(get_highest_layer(layer_state) + 0x30, true);
13
14 led_t led_state = host_keyboard_led_state();
15 oled_set_cursor(18, 0);
16 oled_write_P(PSTR("NUM"), led_state.num_lock);
17 oled_set_cursor(18, 1);
18 oled_write_P(PSTR("CAP"), led_state.caps_lock);
19 oled_set_cursor(18, 2);
20 oled_write_P(PSTR("SCR"), led_state.scroll_lock);
21
22 uint8_t mod_state = get_mods();
23 oled_set_cursor(10, 3);
24 oled_write_P(PSTR("S"), mod_state & MOD_MASK_SHIFT);
25 oled_advance_char();
26 oled_write_P(PSTR("C"), mod_state & MOD_MASK_CTRL);
27 oled_advance_char();
28 oled_write_P(PSTR("A"), mod_state & MOD_MASK_ALT);
29 oled_advance_char();
30 oled_write_P(PSTR("G"), mod_state & MOD_MASK_GUI);
31 oled_advance_char();
32
33/* Matrix display is 12 x 12 pixels */
34#define MATRIX_DISPLAY_X 5
35#define MATRIX_DISPLAY_Y 18
36
37 // matrix
38 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
39 for (uint8_t y = 0; y < MATRIX_COLS; y++) {
40 bool on = (matrix_get_row(x) & (1 << y)) > 0;
41 oled_write_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2, on);
42 }
43 }
44
45 // outline
46 for (uint8_t x = 0; x < 19; x++) {
47 oled_write_pixel(MATRIX_DISPLAY_X + x, MATRIX_DISPLAY_Y, true);
48 oled_write_pixel(MATRIX_DISPLAY_X + x, MATRIX_DISPLAY_Y + 9, true);
49 }
50 for (uint8_t y = 0; y < 9; y++) {
51 oled_write_pixel(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y+y, true);
52 oled_write_pixel(MATRIX_DISPLAY_X + 19, MATRIX_DISPLAY_Y+y, true);
53 }
54
55 // oled location
56 for (uint8_t x = 0; x < 3; x++) {
57 oled_write_pixel(MATRIX_DISPLAY_X + 14 + x, MATRIX_DISPLAY_Y + 2, true);
58 }
59
60 // bodge for layer number left hand side
61 for (uint8_t y = 0; y < 8; y++) {
62 oled_write_pixel(35, 0 + y, true);
63 }
64}
65#endif
diff --git a/keyboards/hadron/ver2/ver2.h b/keyboards/hadron/ver2/ver2.h
index e7577d268..8127b497f 100644
--- a/keyboards/hadron/ver2/ver2.h
+++ b/keyboards/hadron/ver2/ver2.h
@@ -1,3 +1,3 @@
1#pragma once 1#pragma once
2 2
3#include "../hadron.h" 3#include "hadron.h"
diff --git a/keyboards/hadron/ver3/config.h b/keyboards/hadron/ver3/config.h
index 87d01726f..54fab6662 100644
--- a/keyboards/hadron/ver3/config.h
+++ b/keyboards/hadron/ver3/config.h
@@ -69,16 +69,8 @@
69#define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f 69#define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f
70#endif 70#endif
71 71
72//configure qwiic micro_oled driver for the 128x32 oled 72// configure oled driver for the 128x32 oled
73#ifdef QWIIC_MICRO_OLED_ENABLE 73#define OLED_UPDATE_INTERVAL 33 // ~30fps
74
75#undef I2C_ADDRESS_SA0_1
76#define I2C_ADDRESS_SA0_1 0b0111100
77#define LCDWIDTH 128
78#define LCDHEIGHT 32
79#define micro_oled_rotate_180
80
81#endif
82 74
83/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ 75/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
84// #define DEBOUNCE 6 76// #define DEBOUNCE 6
diff --git a/keyboards/hadron/ver3/keymaps/default/config.h b/keyboards/hadron/ver3/keymaps/default/config.h
deleted file mode 100644
index 6f70f09be..000000000
--- a/keyboards/hadron/ver3/keymaps/default/config.h
+++ /dev/null
@@ -1 +0,0 @@
1#pragma once
diff --git a/keyboards/hadron/ver3/keymaps/default/keymap.c b/keyboards/hadron/ver3/keymaps/default/keymap.c
index cec43e95d..b897ffcab 100644
--- a/keyboards/hadron/ver3/keymaps/default/keymap.c
+++ b/keyboards/hadron/ver3/keymaps/default/keymap.c
@@ -9,8 +9,8 @@
9#define _DVORAK 2 9#define _DVORAK 2
10#define _LOWER 3 10#define _LOWER 3
11#define _RAISE 4 11#define _RAISE 4
12#define _MOUSECURSOR 8 12#define _MOUSECURSOR 5
13#define _ADJUST 16 13#define _ADJUST 6
14 14
15enum preonic_keycodes { 15enum preonic_keycodes {
16 QWERTY = SAFE_RANGE, 16 QWERTY = SAFE_RANGE,
diff --git a/keyboards/hadron/ver3/keymaps/readme.md b/keyboards/hadron/ver3/keymaps/readme.md
deleted file mode 100644
index 66bf06b71..000000000
--- a/keyboards/hadron/ver3/keymaps/readme.md
+++ /dev/null
@@ -1,24 +0,0 @@
1# How to add your own keymap
2
3Folders can be named however you'd like (will be approved upon merging), or should follow the format with a preceding `_`:
4
5 _[ISO 3166-1 alpha-2 code*]_[layout variant]_[layout name/author]
6
7\* See full list: https://en.wikipedia.org/wiki/ISO_3166-1#Officially_assigned_code_elements
8
9and contain the following files:
10
11* `keymap.c`
12* `readme.md` *recommended*
13* `config.h` *optional*, found automatically when compiling
14* `Makefile` *optional*, found automatically when compling
15
16When adding your keymap to this list, keep it organised alphabetically (select list, edit->sort lines), and use this format:
17
18 * **folder_name** description
19
20# List of Hadron keymaps
21
22* **default** default Hadron layout
23* **ishtob** ishtob's Hadron layout
24* **sebaslayout** sebaslayout's Hadron layout \ No newline at end of file
diff --git a/keyboards/hadron/ver3/rules.mk b/keyboards/hadron/ver3/rules.mk
index f3cc14b17..ad753a5ff 100644
--- a/keyboards/hadron/ver3/rules.mk
+++ b/keyboards/hadron/ver3/rules.mk
@@ -22,6 +22,6 @@ RGBLIGHT_ENABLE = yes
22RGB_MATRIX_ENABLE = no # once arm_rgb is implemented 22RGB_MATRIX_ENABLE = no # once arm_rgb is implemented
23RGB_MATRIX_DRIVER = WS2812 23RGB_MATRIX_DRIVER = WS2812
24HAPTIC_ENABLE += DRV2605L 24HAPTIC_ENABLE += DRV2605L
25QWIIC_ENABLE = yes 25OLED_ENABLE = yes
26QWIIC_DRIVERS += MICRO_OLED 26OLED_DRIVER = SSD1306
27ENCODER_ENABLER = yes 27ENCODER_ENABLER = yes
diff --git a/keyboards/hadron/ver3/ver3.c b/keyboards/hadron/ver3/ver3.c
index 0664bf4b0..7eabe5855 100644
--- a/keyboards/hadron/ver3/ver3.c
+++ b/keyboards/hadron/ver3/ver3.c
@@ -14,9 +14,6 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#include "ver3.h" 16#include "ver3.h"
17#include "qwiic.h"
18#include "action_layer.h"
19#include "haptic.h"
20 17
21 18
22#ifdef RGB_MATRIX_ENABLE 19#ifdef RGB_MATRIX_ENABLE
@@ -36,185 +33,66 @@ led_config_t g_led_config = { {
36 33
37#endif 34#endif
38 35
39uint8_t *o_fb; 36#ifdef OLED_ENABLE
40
41uint16_t counterst = 0;
42
43
44
45#ifdef QWIIC_MICRO_OLED_ENABLE
46
47/* screen off after this many milliseconds */
48#include "timer.h"
49#define ScreenOffInterval 60000 /* milliseconds */
50static uint16_t last_flush;
51
52volatile uint8_t led_numlock = false;
53volatile uint8_t led_capslock = false;
54volatile uint8_t led_scrolllock = false;
55
56static uint8_t layer;
57static bool queue_for_send = false;
58static uint8_t encoder_value = 32;
59
60__attribute__ ((weak)) 37__attribute__ ((weak))
61void draw_ui(void) { 38oled_rotation_t oled_init_user(oled_rotation_t rotation) {
62 clear_buffer(); 39 return OLED_ROTATION_180;
63 last_flush = timer_read(); 40}
64 send_command(DISPLAYON);
65
66/* Layer indicator is 41 x 10 pixels */
67#define LAYER_INDICATOR_X 5
68#define LAYER_INDICATOR_Y 0
69
70 draw_string(LAYER_INDICATOR_X + 1, LAYER_INDICATOR_Y + 2, "LAYER", PIXEL_ON, NORM, 0);
71 draw_rect_filled_soft(LAYER_INDICATOR_X + 32, LAYER_INDICATOR_Y + 1, 9, 9, PIXEL_ON, NORM);
72 draw_char(LAYER_INDICATOR_X + 34, LAYER_INDICATOR_Y + 2, layer + 0x30, PIXEL_ON, XOR, 0);
73 41
74/* Matrix display is 19 x 9 pixels */ 42__attribute__ ((weak))
43void oled_task_user(void) {
44 oled_write_P(PSTR("LAYER "), false);
45 oled_write_char(get_highest_layer(layer_state) + 0x30, true);
46
47 led_t led_state = host_keyboard_led_state();
48 oled_set_cursor(18, 0);
49 oled_write_P(PSTR("NUM"), led_state.num_lock);
50 oled_set_cursor(18, 1);
51 oled_write_P(PSTR("CAP"), led_state.caps_lock);
52 oled_set_cursor(18, 2);
53 oled_write_P(PSTR("SCR"), led_state.scroll_lock);
54
55 uint8_t mod_state = get_mods();
56 oled_set_cursor(10, 3);
57 oled_write_P(PSTR("S"), mod_state & MOD_MASK_SHIFT);
58 oled_advance_char();
59 oled_write_P(PSTR("C"), mod_state & MOD_MASK_CTRL);
60 oled_advance_char();
61 oled_write_P(PSTR("A"), mod_state & MOD_MASK_ALT);
62 oled_advance_char();
63 oled_write_P(PSTR("G"), mod_state & MOD_MASK_GUI);
64 oled_advance_char();
65
66/* Matrix display is 12 x 12 pixels */
75#define MATRIX_DISPLAY_X 5 67#define MATRIX_DISPLAY_X 5
76#define MATRIX_DISPLAY_Y 18 68#define MATRIX_DISPLAY_Y 18
77 69
78 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 70 // matrix
79 for (uint8_t y = 0; y < MATRIX_COLS; y++) { 71 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
80 draw_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2,(matrix_get_row(x) & (1 << y)) > 0, NORM); 72 for (uint8_t y = 0; y < MATRIX_COLS; y++) {
73 bool on = (matrix_get_row(x) & (1 << y)) > 0;
74 oled_write_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2, on);
75 }
81 } 76 }
82 }
83 draw_rect_soft(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 19, 9, PIXEL_ON, NORM);
84 /* hadron oled location on thumbnail */
85 draw_rect_filled_soft(MATRIX_DISPLAY_X + 14, MATRIX_DISPLAY_Y + 2, 3, 1, PIXEL_ON, NORM);
86/*
87 draw_rect_soft(0, 13, 64, 6, PIXEL_ON, NORM);
88 draw_line_vert(encoder_value, 13, 6, PIXEL_ON, NORM);
89
90*/
91
92/* Mod display is 41 x 16 pixels */
93#define MOD_DISPLAY_X 30
94#define MOD_DISPLAY_Y 18
95
96 uint8_t mods = get_mods();
97 if (mods & MOD_LSFT) {
98 draw_rect_filled_soft(MOD_DISPLAY_X + 0, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
99 draw_string(MOD_DISPLAY_X + 3, MOD_DISPLAY_Y + 2, "S", PIXEL_OFF, NORM, 0);
100 } else {
101 draw_string(MOD_DISPLAY_X + 3, MOD_DISPLAY_Y + 2, "S", PIXEL_ON, NORM, 0);
102 }
103 if (mods & MOD_LCTL) {
104 draw_rect_filled_soft(MOD_DISPLAY_X + 10, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
105 draw_string(MOD_DISPLAY_X + 13, MOD_DISPLAY_Y + 2, "C", PIXEL_OFF, NORM, 0);
106 } else {
107 draw_string(MOD_DISPLAY_X + 13, MOD_DISPLAY_Y + 2, "C", PIXEL_ON, NORM, 0);
108 }
109 if (mods & MOD_LALT) {
110 draw_rect_filled_soft(MOD_DISPLAY_X + 20, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
111 draw_string(MOD_DISPLAY_X + 23, MOD_DISPLAY_Y + 2, "A", PIXEL_OFF, NORM, 0);
112 } else {
113 draw_string(MOD_DISPLAY_X + 23, MOD_DISPLAY_Y + 2, "A", PIXEL_ON, NORM, 0);
114 }
115 if (mods & MOD_LGUI) {
116 draw_rect_filled_soft(MOD_DISPLAY_X + 30, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
117 draw_string(MOD_DISPLAY_X + 33, MOD_DISPLAY_Y + 2, "G", PIXEL_OFF, NORM, 0);
118 } else {
119 draw_string(MOD_DISPLAY_X + 33, MOD_DISPLAY_Y + 2, "G", PIXEL_ON, NORM, 0);
120 }
121
122/* Lock display is 23 x 32 */
123#define LOCK_DISPLAY_X 100
124#define LOCK_DISPLAY_Y 0
125
126 if (led_numlock == true) {
127 draw_rect_filled_soft(LOCK_DISPLAY_X, LOCK_DISPLAY_Y, 5 + (3 * 6), 9, PIXEL_ON, NORM);
128 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 1, "NUM", PIXEL_OFF, NORM, 0);
129 } else if (led_numlock == false) {
130 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 1, "NUM", PIXEL_ON, NORM, 0);
131 }
132 if (led_capslock == true) {
133 draw_rect_filled_soft(LOCK_DISPLAY_X + 0, LOCK_DISPLAY_Y + 11, 5 + (3 * 6), 9, PIXEL_ON, NORM);
134 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 11 +1, "CAP", PIXEL_OFF, NORM, 0);
135 } else if (led_capslock == false) {
136 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 11 +1, "CAP", PIXEL_ON, NORM, 0);
137 }
138 77
139 if (led_scrolllock == true) { 78 // outline
140 draw_rect_filled_soft(LOCK_DISPLAY_X + 0, LOCK_DISPLAY_Y + 22, 5 + (3 * 6), 9, PIXEL_ON, NORM); 79 for (uint8_t x = 0; x < 19; x++) {
141 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 22 +1, "SCR", PIXEL_OFF, NORM, 0); 80 oled_write_pixel(MATRIX_DISPLAY_X + x, MATRIX_DISPLAY_Y, true);
142 } else if (led_scrolllock == false) { 81 oled_write_pixel(MATRIX_DISPLAY_X + x, MATRIX_DISPLAY_Y + 9, true);
143 draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 22 +1, "SCR", PIXEL_ON, NORM, 0);
144 }
145 send_buffer();
146}
147
148void read_host_led_state(void) {
149 uint8_t leds = host_keyboard_leds();
150 if (leds & (1 << USB_LED_NUM_LOCK)) {
151 if (led_numlock == false){
152 led_numlock = true;}
153 } else {
154 if (led_numlock == true){
155 led_numlock = false;}
156 }
157 if (leds & (1 << USB_LED_CAPS_LOCK)) {
158 if (led_capslock == false){
159 led_capslock = true;}
160 } else {
161 if (led_capslock == true){
162 led_capslock = false;}
163 } 82 }
164 if (leds & (1 << USB_LED_SCROLL_LOCK)) { 83 for (uint8_t y = 0; y < 9; y++) {
165 if (led_scrolllock == false){ 84 oled_write_pixel(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y+y, true);
166 led_scrolllock = true;} 85 oled_write_pixel(MATRIX_DISPLAY_X + 19, MATRIX_DISPLAY_Y+y, true);
167 } else {
168 if (led_scrolllock == true){
169 led_scrolllock = false;}
170 } 86 }
171}
172
173uint32_t layer_state_set_kb(uint32_t state) {
174 state = layer_state_set_user(state);
175 layer = biton32(state);
176 queue_for_send = true;
177 return state;
178}
179
180bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
181 queue_for_send = true;
182 return process_record_user(keycode, record);
183}
184
185bool encoder_update_user(uint8_t index, bool clockwise);
186 87
187bool encoder_update_kb(uint8_t index, bool clockwise) { 88 // oled location
188 if (!encoder_update_user(index, clockwise)) return false; 89 for (uint8_t x = 0; x < 3; x++) {
189 encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64; 90 oled_write_pixel(MATRIX_DISPLAY_X + 14 + x, MATRIX_DISPLAY_Y + 2, true);
190 queue_for_send = true; 91 }
191 return true;
192}
193
194#endif
195 92
196void matrix_init_kb(void) { 93 // bodge for layer number left hand side
197 queue_for_send = true; 94 for (uint8_t y = 0; y < 8; y++) {
198 matrix_init_user(); 95 oled_write_pixel(35, 0 + y, true);
96 }
199} 97}
200
201void matrix_scan_kb(void) {
202if (queue_for_send) {
203#ifdef QWIIC_MICRO_OLED_ENABLE
204 read_host_led_state();
205 draw_ui();
206#endif 98#endif
207 queue_for_send = false;
208 }
209#ifdef QWIIC_MICRO_OLED_ENABLE
210 if (timer_elapsed(last_flush) > ScreenOffInterval) {
211 send_command(DISPLAYOFF); /* 0xAE */
212 }
213#endif
214 if (counterst == 0) {
215 //testPatternFB(o_fb);
216 }
217 counterst = (counterst + 1) % 1024;
218 //rgblight_task();
219 matrix_scan_user();
220}