You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
FC-KB/kbdrv-main.c

127 lines
2.9 KiB

#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
#include "./keyboard_mapping.h"
#include <wiringx.h>
/*int columns[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
* int rows[] = {15, 16, 17, 18, 19, 20, 21, 22, 26, 27};
* unsigned char pressed_scancodes[6];
* char kmod = 0;
*/
bool state[sizeof(columns)/sizeof(int)][sizeof(rows)/sizeof(int)];
#define BUF_LEN 512
int main() {
if(wiringXSetup("duo", NULL) == -1){
wiringXGC();
return -1;
}
for(int i = 0; i < sizeof(columns)/sizeof(int); i++){
if(wiringXValidGPIO(columns[i]) != 0){
printf("Invalid GPIO %d\n", columns[i]);
return -1;
}
pinMode(columns[i], PINMODE_OUTPUT);
digitalWrite(columns[i], HIGH);
}
for(int i = 0; i < sizeof(rows)/sizeof(int); i++){
if(wiringXValidGPIO(rows[i]) != 0){
printf("Invalid GPIO %d\n", rows[i]);
return -1;
}
// digitalWrite(rows[i], LOW);
pinMode(rows[i], PINMODE_INPUT);
}
if(wiringXValidGPIO(num_lock) != 0){
printf("Invalid GPIO %d\n", num_lock);
return -1;
}
pinMode(num_lock, PINMODE_OUTPUT);
printf("Ready to start doing keyboard things :)\n");
const char *filename = "/dev/hidg0";
int fd = 0;
fd_set rfds;
char buf[BUF_LEN];
int retval, cmd_len;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 200;
if((fd = open(filename, O_RDWR, 0666)) == -1) {
perror(filename);
return -1;
}
while(true){
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 200;
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if (retval == -1 && errno == EINTR)
continue;
if (retval < 0) {
perror("select()");
return 4;
}
if(FD_ISSET(fd, &rfds)) {
cmd_len = read(fd, buf, BUF_LEN - 1);
for(int i = 0; i < cmd_len; i++){
//CONTROL LEDS
digitalWrite(num_lock, (buf[i] % 2 == 1 ? HIGH : LOW));
}
}
char report[8];
memset(&report, 0x0, 8);
int curKey = 0;
for(int c = 0; c < sizeof(columns)/sizeof(int); c++){
digitalWrite(columns[c], LOW);
for(int r = 0; r < sizeof(rows)/sizeof(int); r++){
char curState = state[c][r];
state[c][r] = (digitalRead(rows[r]) == LOW);
if(state[c][r] == true && curKey < 6){
char *binding = mapping[c][r];
for(int i = 0; kmod[i].opt != NULL; i++){
if (strcmp(binding, kmod[i].opt) == 0) {
report[0] = report[0] | kmod[i].val;
break;
}
}
for(int i = 0; kval[i].opt != NULL; i++){
if(strcmp(binding, kval[i].opt) == 0) {
report[2 + curKey++] = kval[i].val;
break;
}
}
}
if(state[c][r] != curState) printf("statechange to %s column %d, row %d\n", (state[c][r] ? "HIGH" : "LOW"), c, r);
}
digitalWrite(columns[c], HIGH);
}
//printf("Report: ");
//for(int i = 0; i < sizeof(report)/sizeof(char); i++){
// printf("%x ", report[i]);
//}
//printf("\n");
write(fd, report, 8);//Send Report over USB
usleep(1000);
}
close(fd);
return 0;
}