]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/lfkeyboards/mini1800/mini1800.c
Lfkeyboards updates (#2421)
[qmk_firmware.git] / keyboards / lfkeyboards / mini1800 / mini1800.c
1
2 #include <avr/sfr_defs.h>
3 #include <avr/timer_avr.h>
4 #include <avr/wdt.h>
5 #include "mini1800.h"
6 #include "keymap.h"
7 #include "issi.h"
8 #include "TWIlib.h"
9 #include "lighting.h"
10 #include "debug.h"
11
12 #define BACKLIGHT_BREATHING
13 #include "quantum.h"
14
15 uint16_t click_hz = CLICK_HZ;
16 uint16_t click_time = CLICK_MS;
17 uint8_t click_toggle = CLICK_ENABLED;
18 float my_song[][2] = SONG(ZELDA_PUZZLE);
19
20
21 void matrix_init_kb(void)
22 {
23     // put your keyboard start-up code here
24     // runs once when the firmware starts up
25     matrix_init_user();
26     set_rgb(31, 0x00, 0x00, 0x00);  // Caps lock
27     set_rgb(32, 0xFF, 0x00, 0x00);  // Layer indicator, start red
28 #ifndef AUDIO_ENABLE
29     // If we're not using the audio pin, drive it low
30     sbi(DDRC, 6);
31     cbi(PORTC, 6);
32 #endif
33     _delay_ms(500);
34 #ifdef ISSI_ENABLE
35     issi_init();
36 #endif
37 #ifdef WATCHDOG_ENABLE
38     // This is done after turning the layer LED red, if we're caught in a loop
39     // we should get a flashing red light
40     wdt_enable(WDTO_500MS);
41 #endif
42 }
43
44 void matrix_scan_kb(void)
45 {
46 #ifdef WATCHDOG_ENABLE
47     wdt_reset();
48 #endif
49 #ifdef ISSI_ENABLE
50     // switch/underglow lighting update
51     static uint32_t issi_device = 0;
52     static uint32_t twi_last_ready = 0;
53     if(twi_last_ready > 1000){
54         // Its been way too long since the last ISSI update, reset the I2C bus and start again
55         twi_last_ready = 0;
56         TWIInit();
57         force_issi_refresh();
58     }
59     if(isTWIReady()){
60         twi_last_ready = 0;
61         // If the i2c bus is available, kick off the issi update, alternate between devices
62         update_issi(issi_device, issi_device);
63         if(issi_device){
64             issi_device = 0;
65         }else{
66             issi_device = 3;
67         }
68     }else{
69         twi_last_ready++;
70     }
71 #endif
72     // Update layer indicator LED
73     //
74     // Not sure how else to reliably do this... TMK has the 'hook_layer_change'
75     // but can't find QMK equiv
76     static uint32_t layer_indicator = -1;
77     if(layer_indicator != layer_state){
78         for(uint32_t i=0;; i++){
79             // the layer_info list should end with layer 0xFFFF
80             // it will break this out of the loop and define the unknown layer color
81             if((layer_info[i].layer == (layer_state & layer_info[i].mask)) || (layer_info[i].layer == 0xFFFFFFFF)){
82                 set_rgb(32, layer_info[i].color.red, layer_info[i].color.green, layer_info[i].color.blue);
83                 layer_indicator = layer_state;
84                 break;
85             }
86         }
87     }
88     matrix_scan_user();
89 }
90
91 void click(uint16_t freq, uint16_t duration){
92 #ifdef AUDIO_ENABLE
93     if(freq >= 100 && freq <= 20000 && duration < 100){
94         play_note(freq, 10);
95         for (uint16_t i = 0; i < duration; i++){
96             _delay_ms(1);
97         }
98         stop_all_notes();
99     }
100 #endif
101 }
102
103 bool process_record_kb(uint16_t keycode, keyrecord_t* record)
104 {
105     if (click_toggle && record->event.pressed){
106         click(click_hz, click_time);
107     }
108     if (keycode == RESET) {
109         reset_keyboard_kb();
110     } else {
111     }
112     return process_record_user(keycode, record);
113 }
114
115 void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
116 {
117 #ifdef AUDIO_ENABLE
118     int8_t sign = 1;
119 #endif
120     if(id == LFK_ESC_TILDE){
121         // Send ~ on shift-esc
122         void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
123         uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
124         method(shifted ? KC_GRAVE : KC_ESCAPE);
125         send_keyboard_report();
126     }else if(event->event.pressed){
127         switch(id){
128             case LFK_SET_DEFAULT_LAYER:
129                 // set/save the current base layer to eeprom, falls through to LFK_CLEAR
130                 eeconfig_update_default_layer(1UL << opt);
131                 default_layer_set(1UL << opt);
132             case LFK_CLEAR:
133                 // Go back to default layer
134                 layer_clear();
135                 break;
136 #ifdef ISSI_ENABLE
137             case LFK_LED_TEST:
138                 led_test();
139                 break;
140 #endif
141 #ifdef AUDIO_ENABLE
142             case LFK_CLICK_FREQ_LOWER:
143                 sign = -1;  // continue to next statement
144             case LFK_CLICK_FREQ_HIGHER:
145                 click_hz += sign * 100;
146                 click(click_hz, click_time);
147                 break;
148             case LFK_CLICK_TOGGLE:
149                 if(click_toggle){
150                     click_toggle = 0;
151                     click(4000, 100);
152                     click(1000, 100);
153                 }else{
154                     click_toggle = 1;
155                     click(1000, 100);
156                     click(4000, 100);
157                 }
158                 break;
159             case LFK_CLICK_TIME_SHORTER:
160                 sign = -1;  // continue to next statement
161             case LFK_CLICK_TIME_LONGER:
162                 click_time += sign;
163                 click(click_hz, click_time);
164                 break;
165 #endif
166             case LFK_PLAY_ONEUP:
167                 PLAY_SONG(my_song);
168                 break;
169         }
170     }
171 }
172
173 void reset_keyboard_kb(){
174 #ifdef WATCHDOG_ENABLE
175     MCUSR = 0;
176     wdt_disable();
177     wdt_reset();
178 #endif
179     set_rgb(31, 0x00, 0xFF, 0xFF);
180     set_rgb(32, 0x00, 0xFF, 0xFF);
181     force_issi_refresh();
182     reset_keyboard();
183 }
184
185 void led_set_kb(uint8_t usb_led)
186 {
187     // Set capslock LED to Blue
188     if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
189         set_rgb(31, 0x00, 0x00, 0x7F);
190     }else{
191         set_rgb(31, 0x00, 0x00, 0x00);
192     }
193     led_set_user(usb_led);
194 }
195
196 // Lighting info, see lighting.h for details
197 const uint8_t switch_matrices[] = {0, 1};
198 const uint8_t rgb_matrices[] = {6, 7};
199
200 // RGB Map:
201 //   27  29  10   9   8   7   6
202 // 26                                   5
203 // 25                                   4
204 // 24                                   3
205 //   23  22  21  20  14  15  11   1   2
206 const uint8_t rgb_sequence[] = {
207     30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 16
208 };
209
210 // Maps switch LEDs from Row/Col to ISSI matrix.
211 // Value breakdown:
212 //     Bit     | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
213 //             |   | ISSI Col  |    ISSI Row   |
214 //             /   |
215 //             Device
216 const uint8_t switch_leds[MATRIX_ROWS][MATRIX_COLS] =
217 KEYMAP(
218   0x19, 0x18,   0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94,   0x93,   0x92, 0x91,
219   0x29, 0x28,    0x27,  0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0xA9, 0xA8, 0xA7, 0xA6, 0xA5, 0xA4, 0xA3,   0xA2, 0xA1,
220   0x39, 0x38,      0x37,  0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0xB9, 0xB8, 0xB7, 0xB6, 0xB5,     0xB3,
221   0x49, 0x48,    0x47,     0x45, 0x44, 0x43, 0x42, 0x41, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5,          0xC4,   0xC2,
222   0x59, 0x58,   0x57,  0x56,  0x55,             0x51,                   0xD6, 0xE5, 0xE4,         0xE3, 0xE2, 0xE1,
223   0x00, 0x00, 0x00, 0x00);