diff options
Diffstat (limited to 'keyboards/ergodone/expander.c')
-rw-r--r-- | keyboards/ergodone/expander.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/keyboards/ergodone/expander.c b/keyboards/ergodone/expander.c new file mode 100644 index 000000000..0c8a2289c --- /dev/null +++ b/keyboards/ergodone/expander.c | |||
@@ -0,0 +1,120 @@ | |||
1 | #include <stdbool.h> | ||
2 | #include "action.h" | ||
3 | #include "i2cmaster.h" | ||
4 | #include "expander.h" | ||
5 | #include "debug.h" | ||
6 | |||
7 | static uint8_t expander_status = 0; | ||
8 | static uint8_t expander_input = 0; | ||
9 | |||
10 | void expander_config(void); | ||
11 | uint8_t expander_write(uint8_t reg, uint8_t data); | ||
12 | uint8_t expander_read(uint8_t reg, uint8_t *data); | ||
13 | |||
14 | void expander_init(void) | ||
15 | { | ||
16 | i2c_init(); | ||
17 | expander_scan(); | ||
18 | } | ||
19 | |||
20 | void expander_scan(void) | ||
21 | { | ||
22 | dprintf("expander status: %d ... ", expander_status); | ||
23 | uint8_t ret = i2c_start(EXPANDER_ADDR | I2C_WRITE); | ||
24 | if (ret == 0) { | ||
25 | i2c_stop(); | ||
26 | if (expander_status == 0) { | ||
27 | dprintf("attached\n"); | ||
28 | expander_status = 1; | ||
29 | expander_config(); | ||
30 | clear_keyboard(); | ||
31 | } | ||
32 | } | ||
33 | else { | ||
34 | if (expander_status == 1) { | ||
35 | dprintf("detached\n"); | ||
36 | expander_status = 0; | ||
37 | clear_keyboard(); | ||
38 | } | ||
39 | } | ||
40 | dprintf("%d\n", expander_status); | ||
41 | } | ||
42 | |||
43 | void expander_read_cols(void) | ||
44 | { | ||
45 | expander_read(EXPANDER_REG_GPIOA, &expander_input); | ||
46 | } | ||
47 | |||
48 | uint8_t expander_get_col(uint8_t col) | ||
49 | { | ||
50 | if (col > 4) { | ||
51 | col++; | ||
52 | } | ||
53 | return expander_input & (1<<col) ? 1 : 0; | ||
54 | } | ||
55 | |||
56 | matrix_row_t expander_read_row(void) | ||
57 | { | ||
58 | expander_read_cols(); | ||
59 | |||
60 | /* make cols */ | ||
61 | matrix_row_t cols = 0; | ||
62 | for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||
63 | if (expander_get_col(col)) { | ||
64 | cols |= (1UL << (MATRIX_COLS - 1 - col)); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | return cols; | ||
69 | } | ||
70 | |||
71 | void expander_unselect_rows(void) | ||
72 | { | ||
73 | expander_write(EXPANDER_REG_IODIRB, 0xFF); | ||
74 | } | ||
75 | |||
76 | void expander_select_row(uint8_t row) | ||
77 | { | ||
78 | expander_write(EXPANDER_REG_IODIRB, ~(1<<(row+1))); | ||
79 | } | ||
80 | |||
81 | void expander_config(void) | ||
82 | { | ||
83 | expander_write(EXPANDER_REG_IPOLA, 0xFF); | ||
84 | expander_write(EXPANDER_REG_GPPUA, 0xFF); | ||
85 | expander_write(EXPANDER_REG_IODIRB, 0xFF); | ||
86 | } | ||
87 | |||
88 | uint8_t expander_write(uint8_t reg, uint8_t data) | ||
89 | { | ||
90 | if (expander_status == 0) { | ||
91 | return 0; | ||
92 | } | ||
93 | uint8_t ret; | ||
94 | ret = i2c_start(EXPANDER_ADDR | I2C_WRITE); | ||
95 | if (ret) goto stop; | ||
96 | ret = i2c_write(reg); | ||
97 | if (ret) goto stop; | ||
98 | ret = i2c_write(data); | ||
99 | stop: | ||
100 | i2c_stop(); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | uint8_t expander_read(uint8_t reg, uint8_t *data) | ||
105 | { | ||
106 | if (expander_status == 0) { | ||
107 | return 0; | ||
108 | } | ||
109 | uint8_t ret; | ||
110 | ret = i2c_start(EXPANDER_ADDR | I2C_WRITE); | ||
111 | if (ret) goto stop; | ||
112 | ret = i2c_write(reg); | ||
113 | if (ret) goto stop; | ||
114 | ret = i2c_rep_start(EXPANDER_ADDR | I2C_READ); | ||
115 | if (ret) goto stop; | ||
116 | *data = i2c_readNak(); | ||
117 | stop: | ||
118 | i2c_stop(); | ||
119 | return ret; | ||
120 | } | ||