Statistics
| Branch: | Tag: | Revision:

root / MatrixScan.c @ 999f8b6f

History | View | Annotate | Download (4.29 KB)

1
#include "MatrixScan.h"
2
#include <util/delay.h>
3
void setupMatrix(){
4
        // TODO
5
        // setup input pins
6
        DATAINDDR = ((0<<DIN_7) | (0<<DIN_6) | (0<<DIN_5) | (0<<DIN_4) | (0<<DIN_3) | (0<<DIN_2) | (0<<DIN_1) | (0<<DIN_0));
7
        // setup shift register
8
        SHIFTREGDDR |= (1<<SRCLKPIN) | (1<<SRDATAPIN);
9
        clearSR();
10
}
11

    
12
void clockSR(){
13
        SHIFTREGPORT |= (1<<SRCLKPIN);
14
        // TODO add delay here?
15
        SHIFTREGPORT &= ~(1<<SRCLKPIN);
16
}
17

    
18
void pushBit(uint8_t bit){
19
        if(bit != 0){
20
                SHIFTREGPORT |= (1<<SRDATAPIN);
21
                clockSR();
22
                SHIFTREGPORT &= ~(1<<SRDATAPIN);
23
        }
24
        else{
25
                clockSR();
26
        }
27
}  
28

    
29
void clearSR(){
30
        for(uint8_t i = 0; i < 21; i++){
31
                pushBit(0);
32
        }
33
}
34

    
35
void decrementKeystrokes(){
36
        for(uint8_t i = 0; i < 30; i++){
37
                if(detectedKeypress[i][0] > 0){
38
                        detectedKeypress[i][0] = detectedKeypress[i][0]-1;
39
                }
40
        }
41
}
42

    
43
void addKeystroke(uint8_t row, uint8_t col){
44
        // check if the key is already inside the list
45
        for(uint8_t i = 0; i < 30; i++){
46
                if(detectedKeypress[i][0] > 0){
47
                        if(detectedKeypress[i][1] == row && detectedKeypress[i][2] == col){
48
                                if(detectedKeypress[i][0] < MAX_KEYPRESS_COUNT){
49
                                        detectedKeypress[i][0] = detectedKeypress[i][0] + 2;
50
                                }
51
                                return;
52
                        }
53
                }
54
        }
55
        // key not found, find space for the key
56
        for(uint8_t i = 0; i < 30; i++){
57
                if(detectedKeypress[i][0] == 0){
58
                        detectedKeypress[i][0] = 2;
59
                        detectedKeypress[i][1] = row;
60
                        detectedKeypress[i][2] = col;
61
                        return;
62
                }
63
        }
64
}
65

    
66
void setReportData(USB_KeyboardReport_Data_t* const ReportData){
67
        // push initial 1
68
        pushBit(1);
69
        pushBit(0); // to get the 1 on the first output
70
        // set afterglow before we miss it later in case of ghosting
71
        ReportData->Modifier |= modAfterglow;
72
        modAfterglow = 0;
73
        // scan matrix
74
        uint8_t pressedKeys = 0;
75
        for(uint8_t i = 0; i < 19; i++){
76
                _delay_us(15);
77
                matrixState[i] = DATAINPIN;
78
                pushBit(0);
79
        }
80
        // check for ghosting
81
        for(uint8_t i = 0; i < 19-1; i++){
82
                if(matrixState[i] != 0){
83
                        for(uint8_t j = i+1; j < 19; j++){
84
                                if(matrixState[i] == matrixState[j] && !((matrixState[i] == (1<<0)) ||
85
                                 (matrixState[i] == (1<<1)) ||
86
                                 (matrixState[i] == (1<<2)) ||
87
                                 (matrixState[i] == (1<<3)) ||
88
                                 (matrixState[i] == (1<<4)) ||
89
                                 (matrixState[i] == (1<<5)) ||
90
                                 (matrixState[i] == (1<<6)) ||
91
                                 (matrixState[i] == (1<<7)))){
92
                                        return; // ghosting found
93
                                }
94
                        }
95
                }
96
        }
97
        // handle queue
98
        for(uint8_t i = 0; i < 19; i++){
99
                if(matrixState[i] != 0){
100
                        for(uint8_t bit = 0; bit < 8; bit++){
101
                                if(matrixState[i] & (1<<bit)){
102
                                        addKeystroke(bit, i);
103
                                }
104
                        }
105
                }
106
        }
107
        // decrement all keystrokes (we added two before)
108
        decrementKeystrokes();
109
        // check for mods
110
        uint8_t modOffset = 0;
111
        for(uint8_t i = 0; i < 30; i++){
112
                if(detectedKeypress[i][0] > KEYPRESS_TRIGGER_COUNT){
113
                        switch (pgm_read_byte(&mapping[detectedKeypress[i][2]][detectedKeypress[i][1]][0][0])){
114
                                case HID_KEYBOARD_SC_LEFT_CONTROL:
115
                                        ReportData->Modifier |= (1<<0);
116
                                        break;
117
                                case HID_KEYBOARD_SC_LEFT_SHIFT:
118
                                        ReportData->Modifier |= (1<<1);
119
                                        if(modOffset == 0){
120
                                                modOffset = 1;
121
                                        }
122
                                        break;
123
                                case HID_KEYBOARD_SC_LEFT_ALT:
124
                                        ReportData->Modifier |= (1<<2);
125
                                        break;
126
                                case HID_KEYBOARD_SC_LEFT_GUI:
127
                                        ReportData->Modifier |= (1<<3);
128
                                        break;
129
                                case HID_KEYBOARD_SC_RIGHT_CONTROL:
130
                                        ReportData->Modifier |= (1<<4);
131
                                        break;
132
                                case HID_KEYBOARD_SC_RIGHT_SHIFT:
133
                                        ReportData->Modifier |= (1<<5);
134
                                        if(modOffset == 0){
135
                                                modOffset = 1;
136
                                        }
137
                                        break;
138
                                case HID_KEYBOARD_SC_RIGHT_ALT:
139
                                        modOffset = 3;
140
                                        break;
141
                                case HID_KEYBOARD_SC_RIGHT_GUI:
142
                                        ReportData->Modifier |= (1<<7);
143
                                        break;
144
                                case HID_KEYBOARD_SC_MOD3:
145
                                        modOffset = 2;
146
                                        break;
147
                                case HID_KEYBOARD_SC_MOD4:
148
                                        modOffset = 3;
149
                                        break;
150
                                default:
151
                                        break;
152
                        }
153
                }
154
        }
155
        // build report
156
        for(uint8_t i = 0; i < 30; i++){
157
                if(detectedKeypress[i][0] > KEYPRESS_TRIGGER_COUNT){
158
                        if(pressedKeys < 6){
159
                                uint8_t possibleMod = pgm_read_byte(&mapping[detectedKeypress[i][2]][detectedKeypress[i][1]][modOffset][0]);
160
                                if(possibleMod >= HID_KEYBOARD_SC_LEFT_CONTROL && possibleMod <= HID_KEYBOARD_SC_RIGHT_GUI){
161
                                        modAfterglow |= (1<<(possibleMod-0xe0));
162
                                        ReportData->Modifier |= modAfterglow;
163
                                }
164
                                uint8_t possibleKey = pgm_read_byte(&mapping[detectedKeypress[i][2]][detectedKeypress[i][1]][modOffset][1]);
165
                                if(possibleKey != 0){
166
                                        ReportData->KeyCode[pressedKeys++] = possibleKey;
167
                                }
168
                        }
169
                }
170
        }
171
        return;
172
}