]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/ergodox_ez/ergodox_ez.c
09443cf72529bed15484cba780a3ca1ca5a62be9
[qmk_firmware.git] / keyboards / ergodox_ez / ergodox_ez.c
1 #include QMK_KEYBOARD_H
2
3 extern inline void ergodox_board_led_on(void);
4 extern inline void ergodox_right_led_1_on(void);
5 extern inline void ergodox_right_led_2_on(void);
6 extern inline void ergodox_right_led_3_on(void);
7 extern inline void ergodox_right_led_on(uint8_t led);
8
9 extern inline void ergodox_board_led_off(void);
10 extern inline void ergodox_right_led_1_off(void);
11 extern inline void ergodox_right_led_2_off(void);
12 extern inline void ergodox_right_led_3_off(void);
13 extern inline void ergodox_right_led_off(uint8_t led);
14
15 extern inline void ergodox_led_all_on(void);
16 extern inline void ergodox_led_all_off(void);
17
18 extern inline void ergodox_right_led_1_set(uint8_t n);
19 extern inline void ergodox_right_led_2_set(uint8_t n);
20 extern inline void ergodox_right_led_3_set(uint8_t n);
21 extern inline void ergodox_right_led_set(uint8_t led, uint8_t n);
22
23 extern inline void ergodox_led_all_set(uint8_t n);
24
25 bool i2c_initialized = 0;
26 i2c_status_t mcp23018_status = 0x20;
27
28 void matrix_init_kb(void) {
29    // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
30     TCCR1A = 0b10101001;  // set and configure fast PWM
31     TCCR1B = 0b00001001;  // set and configure fast PWM
32
33     // (tied to Vcc for hardware convenience)
34     DDRB  &= ~(1<<4);  // set B(4) as input
35     PORTB &= ~(1<<4);  // set B(4) internal pull-up disabled
36
37     // unused pins - C7, D4, D5, D7, E6
38     // set as input with internal pull-up enabled
39     DDRC  &= ~(1<<7);
40     DDRD  &= ~(1<<5 | 1<<4);
41     DDRE  &= ~(1<<6);
42     PORTC |=  (1<<7);
43     PORTD |=  (1<<5 | 1<<4);
44     PORTE |=  (1<<6);
45
46     ergodox_blink_all_leds();
47
48     matrix_init_user();
49 }
50
51 void ergodox_blink_all_leds(void)
52 {
53     ergodox_led_all_off();
54     ergodox_led_all_set(LED_BRIGHTNESS_DEFAULT);
55     ergodox_right_led_1_on();
56     _delay_ms(50);
57     ergodox_right_led_2_on();
58     _delay_ms(50);
59     ergodox_right_led_3_on();
60     _delay_ms(50);
61 #ifdef LEFT_LEDS
62     ergodox_left_led_1_on();
63     _delay_ms(50);
64     if (!mcp23018_status) {
65       mcp23018_status = ergodox_left_leds_update();
66     }
67     ergodox_left_led_2_on();
68     _delay_ms(50);
69     if (!mcp23018_status) {
70       mcp23018_status = ergodox_left_leds_update();
71     }
72     ergodox_left_led_3_on();
73     _delay_ms(50);
74     if (!mcp23018_status) {
75       mcp23018_status = ergodox_left_leds_update();
76     }
77 #endif
78     ergodox_right_led_1_off();
79     _delay_ms(50);
80     ergodox_right_led_2_off();
81     _delay_ms(50);
82     ergodox_right_led_3_off();
83 #ifdef LEFT_LEDS
84     _delay_ms(50);
85     ergodox_left_led_1_off();
86     if (!mcp23018_status) {
87       mcp23018_status = ergodox_left_leds_update();
88     }
89     _delay_ms(50);
90     ergodox_left_led_2_off();
91     if (!mcp23018_status) {
92       mcp23018_status = ergodox_left_leds_update();
93     }
94     _delay_ms(50);
95     ergodox_left_led_3_off();
96     if (!mcp23018_status) {
97       mcp23018_status = ergodox_left_leds_update();
98     }
99 #endif
100
101     //ergodox_led_all_on();
102     //_delay_ms(333);
103     ergodox_led_all_off();
104 }
105
106 uint8_t init_mcp23018(void) {
107     mcp23018_status = 0x20;
108
109     // I2C subsystem
110
111     // uint8_t sreg_prev;
112     // sreg_prev=SREG;
113     // cli();
114
115     if (i2c_initialized == 0) {
116         i2c_init();  // on pins D(1,0)
117         i2c_initialized = true;
118         _delay_ms(1000);
119     }
120     // i2c_init(); // on pins D(1,0)
121     // _delay_ms(1000);
122
123     // set pin direction
124     // - unused  : input  : 1
125     // - input   : input  : 1
126     // - driving : output : 0
127     mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT);    if (mcp23018_status) goto out;
128     mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT);            if (mcp23018_status) goto out;
129     mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT);        if (mcp23018_status) goto out;
130     mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT);        if (mcp23018_status) goto out;
131     i2c_stop();
132
133     // set pull-up
134     // - unused  : on  : 1
135     // - input   : on  : 1
136     // - driving : off : 0
137     mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT);    if (mcp23018_status) goto out;
138     mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT);             if (mcp23018_status) goto out;
139     mcp23018_status = i2c_write(0b00000000, ERGODOX_EZ_I2C_TIMEOUT);        if (mcp23018_status) goto out;
140     mcp23018_status = i2c_write(0b00111111, ERGODOX_EZ_I2C_TIMEOUT);        if (mcp23018_status) goto out;
141
142 out:
143     i2c_stop();
144
145 #ifdef LEFT_LEDS
146     if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update();
147 #endif // LEFT_LEDS
148
149     // SREG=sreg_prev;
150
151     return mcp23018_status;
152 }
153
154 #ifdef LEFT_LEDS
155 uint8_t ergodox_left_leds_update(void) {
156     if (mcp23018_status) { // if there was an error
157         return mcp23018_status;
158     }
159 #define LEFT_LED_1_SHIFT        7       // in MCP23018 port B
160 #define LEFT_LED_2_SHIFT        6       // in MCP23018 port B
161 #define LEFT_LED_3_SHIFT        7       // in MCP23018 port A
162
163     // set logical value (doesn't matter on inputs)
164     // - unused  : hi-Z : 1
165     // - input   : hi-Z : 1
166     // - driving : hi-Z : 1
167     mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT);
168     if (mcp23018_status) goto out;
169     mcp23018_status = i2c_write(OLATA, ERGODOX_EZ_I2C_TIMEOUT);
170     if (mcp23018_status) goto out;
171     mcp23018_status = i2c_write(0b11111111
172                                 & ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT),
173                                 ERGODOX_EZ_I2C_TIMEOUT);
174     if (mcp23018_status) goto out;
175     mcp23018_status = i2c_write(0b11111111
176                                 & ~(ergodox_left_led_2<<LEFT_LED_2_SHIFT)
177                                 & ~(ergodox_left_led_1<<LEFT_LED_1_SHIFT),
178                                 ERGODOX_EZ_I2C_TIMEOUT);
179     if (mcp23018_status) goto out;
180
181  out:
182     i2c_stop();
183     return mcp23018_status;
184 }
185 #endif
186
187
188 #ifdef SWAP_HANDS_ENABLE
189 __attribute__ ((weak))
190 // swap-hands action needs a matrix to define the swap
191 const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
192     /* Left hand, matrix positions */
193     {{0,13}, {1,13}, {2,13}, {3,13}, {4,13}, {5,13}},
194     {{0,12}, {1,12}, {2,12}, {3,12}, {4,12}, {5,12}},
195     {{0,11}, {1,11}, {2,11}, {3,11}, {4,11}, {5,11}},
196     {{0,10}, {1,10}, {2,10}, {3,10}, {4,10}, {5,10}},
197     {{0,9}, {1,9}, {2,9}, {3,9}, {4,9}, {5,9}},
198     {{0,8}, {1,8}, {2,8}, {3,8}, {4,8}, {5,8}},
199     {{0,7}, {1,7}, {2,7}, {3,7}, {4,7}, {5,7}},
200     /* Right hand, matrix positions */
201     {{0,6}, {1,6}, {2,6}, {3,6}, {4,6}, {5,6}},
202     {{0,5}, {1,5}, {2,5}, {3,5}, {4,5}, {5,5}},
203     {{0,4}, {1,4}, {2,4}, {3,4}, {4,4}, {5,4}},
204     {{0,3}, {1,3}, {2,3}, {3,3}, {4,3}, {5,3}},
205     {{0,2}, {1,2}, {2,2}, {3,2}, {4,2}, {5,2}},
206     {{0,1}, {1,1}, {2,1}, {3,1}, {4,1}, {5,1}},
207     {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
208 };
209 #endif
210
211 #ifdef RGB_MATRIX_ENABLE
212 const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
213 /*   driver
214  *   |  R location
215  *   |  |      G location
216  *   |  |      |      B location
217  *   |  |      |      | */
218     {0, C3_1,  C2_1,  C4_1}, // LED1 on right
219     {0, C6_1,  C5_1,  C7_1}, // LED2
220     {0, C4_2,  C3_2,  C5_2}, // LED3
221     {0, C7_2,  C6_2,  C8_2}, // LED4
222     {0, C2_3,  C1_3,  C3_3}, // LED5
223     {0, C5_3,  C4_3,  C6_3}, // LED6
224     {0, C8_3,  C7_3,  C9_3}, // LED7
225     {0, C2_4,  C1_4,  C3_4}, // LED8
226     {0, C6_4,  C5_4,  C7_4}, // LED9
227     {0, C2_5,  C1_5,  C3_5}, // LED10
228     {0, C7_5,  C6_5,  C8_5}, // LED11
229     {0, C2_6,  C1_6,  C3_6}, // LED12
230     {0, C5_6,  C4_6,  C6_6}, // LED13
231     {0, C8_6,  C7_6,  C9_6}, // LED14
232     {0, C2_7,  C1_7,  C3_7}, // LED15
233     {0, C5_7,  C4_7,  C6_7}, // LED16
234     {0, C2_8,  C1_8,  C3_8}, // LED17
235     {0, C5_8,  C4_8,  C6_8}, // LED18
236
237     {0, C3_9,  C2_9,  C4_9}, // LED19
238     {0, C6_9,  C5_9,  C7_9}, // LED20
239     {0, C4_10, C3_10, C5_10}, // LED21
240     {0, C7_10, C6_10, C8_10}, // LED22
241     {0, C2_11, C1_11, C3_11}, // LED23
242     {0, C5_11, C4_11, C6_11}, // LED24
243
244     {1, C3_1,  C2_1,  C4_1}, // LED1 on left
245     {1, C6_1,  C5_1,  C7_1}, // LED2
246     {1, C4_2,  C3_2,  C5_2}, // LED3
247     {1, C7_2,  C6_2,  C8_2}, // LED4
248     {1, C2_3,  C1_3,  C3_3}, // LED5
249     {1, C5_3,  C4_3,  C6_3}, // LED6
250     {1, C8_3,  C7_3,  C9_3}, // LED7
251     {1, C2_4,  C1_4,  C3_4}, // LED8
252     {1, C6_4,  C5_4,  C7_4}, // LED9
253     {1, C2_5,  C1_5,  C3_5}, // LED10
254     {1, C7_5,  C6_5,  C8_5}, // LED11
255     {1, C2_6,  C1_6,  C3_6}, // LED12
256     {1, C5_6,  C4_6,  C6_6}, // LED13
257     {1, C8_6,  C7_6,  C9_6}, // LED14
258     {1, C2_7,  C1_7,  C3_7}, // LED15
259     {1, C5_7,  C4_7,  C6_7}, // LED16
260     {1, C2_8,  C1_8,  C3_8}, // LED17
261     {1, C5_8,  C4_8,  C6_8}, // LED18
262
263     {1, C3_9,  C2_9,  C4_9}, // LED19
264     {1, C6_9,  C5_9,  C7_9}, // LED20
265     {1, C4_10, C3_10, C5_10}, // LED21
266     {1, C7_10, C6_10, C8_10}, // LED22
267     {1, C2_11, C1_11, C3_11}, // LED23
268     {1, C5_11, C4_11, C6_11} // LED24
269 };
270
271
272 led_config_t g_led_config = { {
273     { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
274     {  28,  33,  38,  43,  47, NO_LED },
275     {  27,  32,  37,  42,  46, NO_LED },
276     {  26,  31,  36,  41,  45, NO_LED },
277     {  25,  30,  35,  40,  44, NO_LED },
278     {  24,  29,  34,  39, NO_LED, NO_LED },
279     { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
280     { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
281     {   0,   5,  10,  15, NO_LED, NO_LED },
282     {   1,   6,  11,  16,  20, NO_LED },
283     {   2,   7,  12,  17,  21, NO_LED },
284     {   3,   8,  13,  18,  22, NO_LED },
285     {   4,   9,  14,  19,  23, NO_LED },
286     { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED }
287 }, {
288     { 137,   0 }, { 154,   0 }, { 172,   0 }, { 189,   0 }, { 206,   0 }, { 137,  12 },
289     { 154,  12 }, { 172,  12 }, { 189,  12 }, { 206,  12 }, { 137,  25 }, { 154,  25 },
290     { 172,  25 }, { 189,  25 }, { 206,  25 }, { 137,  38 }, { 154,  38 }, { 172,  38 },
291     { 189,  38 }, { 206,  38 }, { 154,  51 }, { 172,  51 }, { 189,  51 }, { 206,  51 },
292     {  86,   0 }, {  68,   0 }, {  51,   0 }, {  34,   0 }, {  17,   0 }, {  86,  12 },
293     {  68,  12 }, {  51,  12 }, {  34,  12 }, {  17,  12 }, {  86,  25 }, {  68,  25 },
294     {  51,  25 }, {  34,  25 }, {  17,  25 }, {  86,  38 }, {  68,  38 }, {  51,  38 },
295     {  34,  38 }, {  17,  38 }, {  68,  51 }, {  51,  51 }, {  34,  51 }, {  17,  51 }
296 }, {
297     4, 4, 4, 4, 4, 4,
298     4, 4, 4, 4, 4, 4,
299     4, 4, 4, 4, 4, 4,
300     4, 4, 1, 1, 1, 1,
301     4, 4, 4, 4, 4, 4,
302     4, 4, 4, 4, 4, 4,
303     4, 4, 4, 4, 4, 4,
304     4, 4, 1, 1, 1, 1
305 } };
306
307 #endif