diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index eda0043..8fd127a 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -51,7 +51,7 @@ uint32_t usage; uint8_t size; int32_t min, max; - bool discard, relative, isSigned; + bool discard, relative, isSigned, reportsUsage; UsagePage *usagePage; } InputReader; diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index eda0043..8fd127a 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -51,7 +51,7 @@ uint32_t usage; uint8_t size; int32_t min, max; - bool discard, relative, isSigned; + bool discard, relative, isSigned, reportsUsage; UsagePage *usagePage; } InputReader; diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 279931e..d124e62 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,7 +26,7 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders, bool reportsUsage) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; reader->usagePage = state->usagePage; @@ -36,6 +36,7 @@ reader->isSigned = state->logicalMin > state->logicalMax; reader->min = state->logicalMin; reader->max = state->logicalMax; + reader->reportsUsage = reportsUsage; listAdd(inputReaders, reader); } @@ -73,22 +74,26 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, i, data, inputReaders); + insertInputReader(state, i, data, inputReaders, false); } } else if (usageCount == 1) { uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); } } else if (usageCount == state->reportCount) { - printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; foreach (state->usages, void *, usage, { - insertInputReader(state, U32(usage), data, inputReaders); + insertInputReader(state, U32(usage), data, inputReaders, false); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); + } + } else if (usageCount == 0 && (state->logicalMin == state->usageMin && state->logicalMax == state->usageMax)) { + // TODO: figure out exact condition for this + for (uint32_t i = 0; i < state->reportCount; i++) { + insertInputReader(state, 0, data, inputReaders, true); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -183,9 +188,10 @@ request(device->serviceId, device->normalFunction, device->deviceId, U32(getPhysicalAddress(device->buffer))); uint32_t *report = device->buffer; uint8_t bit = 0; + printf("keyboard test: %x\n", *report); foreach (device->inputReaders, InputReader *, reader, { uint32_t data = consumeBits(&report, &bit, reader->size); - if (reader->discard) { + if (reader->discard || bit >= 32) { continue; } int32_t processedData = data; @@ -197,7 +203,12 @@ processedData = (int32_t)(int16_t) data; } } - handleUsage(reader->usagePage, reader->usage, processedData); + if (reader->reportsUsage) { + handleUsage(reader->usagePage, processedData, 1); + printf("keyboard test: %i\n", processedData); + } else { + handleUsage(reader->usagePage, reader->usage, processedData); + } }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index eda0043..8fd127a 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -51,7 +51,7 @@ uint32_t usage; uint8_t size; int32_t min, max; - bool discard, relative, isSigned; + bool discard, relative, isSigned, reportsUsage; UsagePage *usagePage; } InputReader; diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 279931e..d124e62 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,7 +26,7 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders, bool reportsUsage) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; reader->usagePage = state->usagePage; @@ -36,6 +36,7 @@ reader->isSigned = state->logicalMin > state->logicalMax; reader->min = state->logicalMin; reader->max = state->logicalMax; + reader->reportsUsage = reportsUsage; listAdd(inputReaders, reader); } @@ -73,22 +74,26 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, i, data, inputReaders); + insertInputReader(state, i, data, inputReaders, false); } } else if (usageCount == 1) { uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); } } else if (usageCount == state->reportCount) { - printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; foreach (state->usages, void *, usage, { - insertInputReader(state, U32(usage), data, inputReaders); + insertInputReader(state, U32(usage), data, inputReaders, false); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); + } + } else if (usageCount == 0 && (state->logicalMin == state->usageMin && state->logicalMax == state->usageMax)) { + // TODO: figure out exact condition for this + for (uint32_t i = 0; i < state->reportCount; i++) { + insertInputReader(state, 0, data, inputReaders, true); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -183,9 +188,10 @@ request(device->serviceId, device->normalFunction, device->deviceId, U32(getPhysicalAddress(device->buffer))); uint32_t *report = device->buffer; uint8_t bit = 0; + printf("keyboard test: %x\n", *report); foreach (device->inputReaders, InputReader *, reader, { uint32_t data = consumeBits(&report, &bit, reader->size); - if (reader->discard) { + if (reader->discard || bit >= 32) { continue; } int32_t processedData = data; @@ -197,7 +203,12 @@ processedData = (int32_t)(int16_t) data; } } - handleUsage(reader->usagePage, reader->usage, processedData); + if (reader->reportsUsage) { + handleUsage(reader->usagePage, processedData, 1); + printf("keyboard test: %i\n", processedData); + } else { + handleUsage(reader->usagePage, reader->usage, processedData); + } }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/usagePages/keyboard.c b/src/userland/hid/usagePages/keyboard.c new file mode 100644 index 0000000..5248a5e --- /dev/null +++ b/src/userland/hid/usagePages/keyboard.c @@ -0,0 +1,23 @@ +#include + +// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf +// section 10, page 53, table 12 + +char keycodes[] = { + 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\n' +}; + +REQUEST(doKeyCallback, "ioManager", "keyCallback"); + +void handleKeyboard(uint32_t usage, int32_t data) { + if (usage == 0) { + return; + } + if (usage >= sizeof(keycodes) / sizeof(char)) { + // doKeyCallback('E', 0); + } else { + doKeyCallback(keycodes[usage], 0); + } +} diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index eda0043..8fd127a 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -51,7 +51,7 @@ uint32_t usage; uint8_t size; int32_t min, max; - bool discard, relative, isSigned; + bool discard, relative, isSigned, reportsUsage; UsagePage *usagePage; } InputReader; diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 279931e..d124e62 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,7 +26,7 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders, bool reportsUsage) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; reader->usagePage = state->usagePage; @@ -36,6 +36,7 @@ reader->isSigned = state->logicalMin > state->logicalMax; reader->min = state->logicalMin; reader->max = state->logicalMax; + reader->reportsUsage = reportsUsage; listAdd(inputReaders, reader); } @@ -73,22 +74,26 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, i, data, inputReaders); + insertInputReader(state, i, data, inputReaders, false); } } else if (usageCount == 1) { uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); } } else if (usageCount == state->reportCount) { - printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; foreach (state->usages, void *, usage, { - insertInputReader(state, U32(usage), data, inputReaders); + insertInputReader(state, U32(usage), data, inputReaders, false); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); + } + } else if (usageCount == 0 && (state->logicalMin == state->usageMin && state->logicalMax == state->usageMax)) { + // TODO: figure out exact condition for this + for (uint32_t i = 0; i < state->reportCount; i++) { + insertInputReader(state, 0, data, inputReaders, true); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -183,9 +188,10 @@ request(device->serviceId, device->normalFunction, device->deviceId, U32(getPhysicalAddress(device->buffer))); uint32_t *report = device->buffer; uint8_t bit = 0; + printf("keyboard test: %x\n", *report); foreach (device->inputReaders, InputReader *, reader, { uint32_t data = consumeBits(&report, &bit, reader->size); - if (reader->discard) { + if (reader->discard || bit >= 32) { continue; } int32_t processedData = data; @@ -197,7 +203,12 @@ processedData = (int32_t)(int16_t) data; } } - handleUsage(reader->usagePage, reader->usage, processedData); + if (reader->reportsUsage) { + handleUsage(reader->usagePage, processedData, 1); + printf("keyboard test: %i\n", processedData); + } else { + handleUsage(reader->usagePage, reader->usage, processedData); + } }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/usagePages/keyboard.c b/src/userland/hid/usagePages/keyboard.c new file mode 100644 index 0000000..5248a5e --- /dev/null +++ b/src/userland/hid/usagePages/keyboard.c @@ -0,0 +1,23 @@ +#include + +// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf +// section 10, page 53, table 12 + +char keycodes[] = { + 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\n' +}; + +REQUEST(doKeyCallback, "ioManager", "keyCallback"); + +void handleKeyboard(uint32_t usage, int32_t data) { + if (usage == 0) { + return; + } + if (usage >= sizeof(keycodes) / sizeof(char)) { + // doKeyCallback('E', 0); + } else { + doKeyCallback(keycodes[usage], 0); + } +} diff --git a/src/userland/hid/usagePages/usagePages.c b/src/userland/hid/usagePages/usagePages.c index 91e3ad0..9be2094 100644 --- a/src/userland/hid/usagePages/usagePages.c +++ b/src/userland/hid/usagePages/usagePages.c @@ -2,6 +2,7 @@ extern Usage genericDesktopControlsUsages[]; extern void handleButton(uint32_t usage, int32_t data); +extern void handleKeyboard(uint32_t usage, int32_t data); // https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf // page 14, section 3, table 1: Usage Page Summary @@ -29,7 +30,7 @@ .usages = NULL, }, { .name = "Keyboard/Keypad", - .usages = NULL, + .handle = handleKeyboard, }, { .name = "LEDs", .usages = NULL, diff --git a/src/userland/hid/include/hid.h b/src/userland/hid/include/hid.h index eda0043..8fd127a 100644 --- a/src/userland/hid/include/hid.h +++ b/src/userland/hid/include/hid.h @@ -51,7 +51,7 @@ uint32_t usage; uint8_t size; int32_t min, max; - bool discard, relative, isSigned; + bool discard, relative, isSigned, reportsUsage; UsagePage *usagePage; } InputReader; diff --git a/src/userland/hid/main.c b/src/userland/hid/main.c index 279931e..d124e62 100644 --- a/src/userland/hid/main.c +++ b/src/userland/hid/main.c @@ -26,7 +26,7 @@ printf("%pCollection(%s)\n", padding, collectionType); } -void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders) { +void insertInputReader(ReportParserState *state, uint32_t usage, uint32_t data, ListElement **inputReaders, bool reportsUsage) { InputReader *reader = malloc(sizeof(InputReader)); reader->size = state->reportSize; reader->usagePage = state->usagePage; @@ -36,6 +36,7 @@ reader->isSigned = state->logicalMin > state->logicalMax; reader->min = state->logicalMin; reader->max = state->logicalMax; + reader->reportsUsage = reportsUsage; listAdd(inputReaders, reader); } @@ -73,22 +74,26 @@ if (data >> 0 & 1) { // data is constant, no need to keep track of it for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, i, data, inputReaders); + insertInputReader(state, i, data, inputReaders, false); } } else if (usageCount == 1) { uint32_t usage = U32(listGet(state->usages, 0)); for (uint32_t i = 0; i < state->reportCount; i++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); } } else if (usageCount == state->reportCount) { - printf("%p New input has the following usages:\n", state->padding); uint32_t i = 0; foreach (state->usages, void *, usage, { - insertInputReader(state, U32(usage), data, inputReaders); + insertInputReader(state, U32(usage), data, inputReaders, false); }); } else if (usageCount == 0 && (state->usageMax - state->usageMin + 1 == state->reportCount)) { for (uint32_t usage = state->usageMin; usage <= state->usageMax; usage++) { - insertInputReader(state, usage, data, inputReaders); + insertInputReader(state, usage, data, inputReaders, false); + } + } else if (usageCount == 0 && (state->logicalMin == state->usageMin && state->logicalMax == state->usageMax)) { + // TODO: figure out exact condition for this + for (uint32_t i = 0; i < state->reportCount; i++) { + insertInputReader(state, 0, data, inputReaders, true); } } else { printf("%p Input parser cannot deduce the usage of the reports, having %i reports and %i usages\n", @@ -183,9 +188,10 @@ request(device->serviceId, device->normalFunction, device->deviceId, U32(getPhysicalAddress(device->buffer))); uint32_t *report = device->buffer; uint8_t bit = 0; + printf("keyboard test: %x\n", *report); foreach (device->inputReaders, InputReader *, reader, { uint32_t data = consumeBits(&report, &bit, reader->size); - if (reader->discard) { + if (reader->discard || bit >= 32) { continue; } int32_t processedData = data; @@ -197,7 +203,12 @@ processedData = (int32_t)(int16_t) data; } } - handleUsage(reader->usagePage, reader->usage, processedData); + if (reader->reportsUsage) { + handleUsage(reader->usagePage, processedData, 1); + printf("keyboard test: %i\n", processedData); + } else { + handleUsage(reader->usagePage, reader->usage, processedData); + } }); // TODO: sleep for at least endpoint->interval? sleep(10); diff --git a/src/userland/hid/usagePages/keyboard.c b/src/userland/hid/usagePages/keyboard.c new file mode 100644 index 0000000..5248a5e --- /dev/null +++ b/src/userland/hid/usagePages/keyboard.c @@ -0,0 +1,23 @@ +#include + +// https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf +// section 10, page 53, table 12 + +char keycodes[] = { + 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\n' +}; + +REQUEST(doKeyCallback, "ioManager", "keyCallback"); + +void handleKeyboard(uint32_t usage, int32_t data) { + if (usage == 0) { + return; + } + if (usage >= sizeof(keycodes) / sizeof(char)) { + // doKeyCallback('E', 0); + } else { + doKeyCallback(keycodes[usage], 0); + } +} diff --git a/src/userland/hid/usagePages/usagePages.c b/src/userland/hid/usagePages/usagePages.c index 91e3ad0..9be2094 100644 --- a/src/userland/hid/usagePages/usagePages.c +++ b/src/userland/hid/usagePages/usagePages.c @@ -2,6 +2,7 @@ extern Usage genericDesktopControlsUsages[]; extern void handleButton(uint32_t usage, int32_t data); +extern void handleKeyboard(uint32_t usage, int32_t data); // https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf // page 14, section 3, table 1: Usage Page Summary @@ -29,7 +30,7 @@ .usages = NULL, }, { .name = "Keyboard/Keypad", - .usages = NULL, + .handle = handleKeyboard, }, { .name = "LEDs", .usages = NULL, diff --git a/src/userland/ioManager/main.c b/src/userland/ioManager/main.c index f0452fb..a47e48a 100644 --- a/src/userland/ioManager/main.c +++ b/src/userland/ioManager/main.c @@ -122,7 +122,7 @@ int32_t main() { ioManager = getServiceId(); logFunction = createFunction("", (void *)handleLog); - keyCallback = createFunction("", (void *)handleKey); + keyCallback = createFunction("keyCallback", (void *)handleKey); createFunction("checkFocus", (void *)checkFocus); mainService = loadFromInitrd("vga"); mainOut = getFunction(mainService, "writeChar");