]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboard/ergodox_ez/ergodox_ez.c
[Jack & Erez] Comments + tiny updates and cleanup
[qmk_firmware.git] / keyboard / ergodox_ez / ergodox_ez.c
1 #include "ergodox_ez.h"
2 #include "i2cmaster.h"
3
4 bool i2c_initialized = 0;
5 uint8_t mcp23018_status = 0x20;
6
7 bool ergodox_left_led_1 = 0;  // left top
8 bool ergodox_left_led_2 = 0;  // left middle
9 bool ergodox_left_led_3 = 0;  // left bottom
10
11 __attribute__ ((weak))
12 void * matrix_init_user(void) {
13
14 };
15
16 __attribute__ ((weak))
17 void * matrix_scan_user(void) {
18
19 };
20
21 void * matrix_init_kb(void) {
22    // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
23     TCCR1A = 0b10101001;  // set and configure fast PWM
24     TCCR1B = 0b00001001;  // set and configure fast PWM
25
26     // (tied to Vcc for hardware convenience)
27     DDRB  &= ~(1<<4);  // set B(4) as input
28     PORTB &= ~(1<<4);  // set B(4) internal pull-up disabled
29
30     // unused pins - C7, D4, D5, D7, E6
31     // set as input with internal pull-ip enabled
32     DDRC  &= ~(1<<7);
33     DDRD  &= ~(1<<7 | 1<<5 | 1<<4);
34     DDRE  &= ~(1<<6);
35     PORTC |=  (1<<7);
36     PORTD |=  (1<<7 | 1<<5 | 1<<4);
37     PORTE |=  (1<<6);
38
39     ergodox_blink_all_leds();
40
41         if (matrix_init_user) {
42                 (*matrix_init_user)();
43         }
44 };
45
46 void * matrix_scan_kb(void) {
47
48         if (matrix_scan_user) {
49                 (*matrix_scan_user)();
50         }
51 };
52
53
54 void ergodox_blink_all_leds(void)
55 {
56     ergodox_led_all_off();
57     ergodox_led_all_set(LED_BRIGHTNESS_HI);
58     ergodox_led_all_on();
59     _delay_ms(333);
60     ergodox_led_all_off();
61 }
62
63 uint8_t init_mcp23018(void) {
64     mcp23018_status = 0x20;
65
66     // I2C subsystem
67     if (i2c_initialized == 0) {
68         i2c_init();  // on pins D(1,0)
69         i2c_initialized++;
70         _delay_ms(1000);
71     }
72
73     // set pin direction
74     // - unused  : input  : 1
75     // - input   : input  : 1
76     // - driving : output : 0
77     mcp23018_status = i2c_start(I2C_ADDR_WRITE);    if (mcp23018_status) goto out;
78     mcp23018_status = i2c_write(IODIRA);            if (mcp23018_status) goto out;
79     mcp23018_status = i2c_write(0b00000000);        if (mcp23018_status) goto out;
80     mcp23018_status = i2c_write(0b00111111);        if (mcp23018_status) goto out;
81     i2c_stop();
82
83     // set pull-up
84     // - unused  : on  : 1
85     // - input   : on  : 1
86     // - driving : off : 0
87     mcp23018_status = i2c_start(I2C_ADDR_WRITE);    if (mcp23018_status) goto out;
88     mcp23018_status = i2c_write(GPPUA);             if (mcp23018_status) goto out;
89     mcp23018_status = i2c_write(0b00000000);        if (mcp23018_status) goto out;
90     mcp23018_status = i2c_write(0b00111111);        if (mcp23018_status) goto out;
91
92 out:
93     i2c_stop();
94
95     if (!mcp23018_status) mcp23018_status = ergodox_left_leds_update();
96
97     return mcp23018_status;
98 }
99
100 uint8_t ergodox_left_leds_update(void) {
101     if (mcp23018_status) { // if there was an error
102         return mcp23018_status;
103     }
104
105     // set logical value (doesn't matter on inputs)
106     // - unused  : hi-Z : 1
107     // - input   : hi-Z : 1
108     // - driving : hi-Z : 1
109     mcp23018_status = i2c_start(I2C_ADDR_WRITE);    if (mcp23018_status) goto out;
110     mcp23018_status = i2c_write(OLATA);             if (mcp23018_status) goto out;
111     mcp23018_status = i2c_write(0b11111111
112             & ~(ergodox_left_led_3<<LEFT_LED_3_SHIFT)
113           );                                        if (mcp23018_status) goto out;
114     mcp23018_status = i2c_write(0b11111111
115             & ~(ergodox_left_led_2<<LEFT_LED_2_SHIFT)
116             & ~(ergodox_left_led_1<<LEFT_LED_1_SHIFT)
117           );                                        if (mcp23018_status) goto out;
118
119 out:
120     i2c_stop();
121     return mcp23018_status;
122 }
123