Skip to content

Commit 4bee76d

Browse files
committed
Fix errors during profile control
1 parent ebd23f4 commit 4bee76d

File tree

3 files changed

+136
-46
lines changed

3 files changed

+136
-46
lines changed

libmk/libmk.c

Lines changed: 87 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,11 @@ typedef enum LibMK_Effect LibMK_Effect;
4141
typedef struct LibMK_Device LibMK_Device;
4242

4343
/** Constants */
44-
const unsigned char HEADER_DEFAULT = 0x41; // 0100 0001
45-
const unsigned char HEADER_EFFECT = 0x50; // 0101 0000
44+
const unsigned char HEADER_SET = 0x51; // 1001 0001
45+
const unsigned char HEADER_GET = 0x52; // 1001 0010
46+
4647
const unsigned char HEADER_FULL_COLOR = 0xc0; // 1100 0000
4748
const unsigned char HEADER_ERROR = 0xFF; // 1111 1111
48-
const unsigned char OPCODE_ENABLE = 0x02; // 0000 0010
49-
const unsigned char OPCODE_DISABLE = 0x00; // 0000 0000
5049
const unsigned char OPCODE_EFFECT = 0x28; // 0010 1000
5150
const unsigned char OPCODE_ALL_LED = 0xA8; // 1010 1000
5251
const unsigned char OPCODE_EFFECT_ARGS = 0x2c; // 0010 1100
@@ -451,14 +450,17 @@ int libmk_enable_control(LibMK_Handle* handle) {
451450

452451

453452
int libmk_send_control_packet(LibMK_Handle* handle) {
454-
unsigned char* disable = libmk_build_packet(
455-
2, 0x41, 0x01);
456-
int r = libmk_send_packet(handle, disable);
453+
r = libmk_set_control_mode(handle, LIBMK_CUSTOM_CTRL);
457454
if (r != LIBMK_SUCCESS)
455+
return LIBMK_ERR_SEND;
456+
LibMK_Firmware* fw;
457+
r = libmk_get_firmware_version(handle, &fw);
458+
if (r != LIBMK_SUCCESS) {
459+
libusb_close(handle->handle);
458460
return r;
459-
unsigned char* packet = libmk_build_packet(
460-
2, HEADER_DEFAULT, OPCODE_ENABLE);
461-
return libmk_send_packet(handle, packet);
461+
}
462+
handle->layout = fw->layout;
463+
return LIBMK_SUCCESS;
462464
}
463465

464466

@@ -468,11 +470,7 @@ int libmk_disable_control(LibMK_Handle* handle) {
468470
if (handle == NULL)
469471
return LIBMK_ERR_DEV_NOT_SET;
470472

471-
int r;
472-
473-
unsigned char* packet = libmk_build_packet(
474-
2, HEADER_DEFAULT, OPCODE_DISABLE);
475-
r = libmk_send_packet(handle, packet);
473+
int r = libmk_set_control_mode(handle, LIBMK_FIRMWARE_CTRL);
476474
if (r != LIBMK_SUCCESS)
477475
return r;
478476

@@ -525,8 +523,7 @@ int libmk_set_effect(LibMK_Handle* handle, LibMK_Effect effect) {
525523
if (r != LIBMK_SUCCESS)
526524
return r;
527525
packet = libmk_build_packet(
528-
5, HEADER_DEFAULT | HEADER_EFFECT, OPCODE_EFFECT,
529-
0x00, 0x00, (unsigned char) effect);
526+
5, HEADER_SET, OPCODE_EFFECT, 0x00, 0x00, (unsigned char) effect);
530527
return libmk_send_packet(handle, packet);
531528
}
532529

@@ -546,6 +543,40 @@ int libmk_set_full_color(LibMK_Handle* handle,
546543

547544

548545
int libmk_send_packet(LibMK_Handle* handle, unsigned char* packet) {
546+
<<<<<<< HEAD
547+
=======
548+
/** Send a single packet of data to the specified device
549+
*
550+
* Calls libmk_send_recv_packet but instructs it not to care about
551+
* receiving a response.
552+
*/
553+
return libmk_send_recv_packet(handle, packet, true);
554+
}
555+
556+
557+
int libmk_send_recv_packet(
558+
LibMK_Handle* handle, unsigned char* packet, bool response_required) {
559+
/** Send a single packet of data to the specified device
560+
*
561+
* The device operates in INTERRUPT mode, expects 64 bytes of data
562+
* every time. First sends the packet to the device OUT endpoint,
563+
* then reads a packet from the device IN endpoint. If the packet
564+
* was correctly formatted, this received packet has the same header
565+
* as the packet sent. If the header is HEADER_ERROR, then a
566+
* protocol error has occurred and the packet was rejected.
567+
*
568+
* response_required: Boolean argument that determines whether an
569+
* acknowledgement packet is required from the keyboard. Nearly
570+
* all operations yield a confirmation packet, but some do not. If
571+
* it is not required, the function will still attempt to retrieve
572+
* a response, but not care if it is not available.
573+
*/
574+
if (handle == NULL)
575+
handle = DeviceHandle;
576+
if (handle == NULL)
577+
return LIBMK_ERR_DEV_NOT_SET;
578+
579+
>>>>>>> 748c903... Fix errors during profile control
549580
int t, result;
550581
int r = libusb_interrupt_transfer(
551582
handle->handle, LIBMK_EP_OUT | LIBUSB_ENDPOINT_OUT,
@@ -564,9 +595,9 @@ int libmk_send_packet(LibMK_Handle* handle, unsigned char* packet) {
564595
#ifdef LIBMK_DEBUG
565596
libmk_print_packet(packet, "Response");
566597
#endif // LIBMK_DEBUG
567-
if (r != LIBUSB_SUCCESS) {
598+
if (r != LIBUSB_SUCCESS && response_required) {
568599
result = LIBMK_ERR_TRANSFER;
569-
} else if (t != LIBMK_PACKET_SIZE) {
600+
} else if (t != LIBMK_PACKET_SIZE && response_required) {
570601
result = LIBMK_ERR_TRANSFER;
571602
} else if (packet[0] == HEADER_ERROR) {
572603
libmk_print_packet(packet, "Error response");
@@ -583,13 +614,19 @@ int libmk_exch_packet(LibMK_Handle* handle, unsigned char* packet) {
583614
int r = libusb_interrupt_transfer(
584615
handle->handle, LIBMK_EP_OUT | LIBUSB_ENDPOINT_OUT,
585616
packet, LIBMK_PACKET_SIZE, &t, LIBMK_PACKET_TIMEOUT);
617+
#ifdef LIBMK_DEBUG
618+
libmk_print_packet(packet, "Sent");
619+
#endif // LIBMK_DEBUG
586620
if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE) {
587621
free(packet);
588622
return LIBMK_ERR_TRANSFER;
589623
}
590624
r = libusb_interrupt_transfer(
591625
handle->handle, LIBMK_EP_IN | LIBUSB_ENDPOINT_IN,
592626
packet, LIBMK_PACKET_SIZE, &t, LIBMK_PACKET_TIMEOUT);
627+
#ifdef LIBMK_DEBUG
628+
libmk_print_packet(packet, "Received");
629+
#endif // LIBMK_DEBUG
593630
if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE)
594631
return LIBMK_ERR_TRANSFER;
595632
return LIBMK_SUCCESS;
@@ -636,9 +673,7 @@ int libmk_set_all_led_color(LibMK_Handle* handle, unsigned char* colors) {
636673
unsigned char* packets[LIBMK_ALL_LED_PCK_NUM];
637674

638675
for (short i = 0; i < LIBMK_ALL_LED_PCK_NUM; i++)
639-
packets[i] = libmk_build_packet(
640-
3, HEADER_DEFAULT | HEADER_EFFECT,
641-
OPCODE_ALL_LED, (unsigned char) i * 2);
676+
packets[i] = libmk_build_packet(3, HEADER_SET, 0xA8, (unsigned char) i * 2);
642677

643678
unsigned char offset;
644679
int packet, index, result;
@@ -698,7 +733,7 @@ int libmk_set_single_led(
698733
handle = DeviceHandle;
699734
if (handle == NULL)
700735
return LIBMK_ERR_DEV_NOT_SET;
701-
int result = libmk_send_control_packet(handle);
736+
int result = libmk_set_control_mode(handle, LIBMK_CUSTOM_CTRL);
702737
if (result != LIBMK_SUCCESS)
703738
return result;
704739
unsigned char offset;
@@ -718,7 +753,7 @@ int libmk_set_effect_details(
718753
if (handle == NULL)
719754
return LIBMK_ERR_DEV_NOT_SET;
720755
unsigned char* packet = libmk_build_packet(
721-
10, HEADER_DEFAULT | HEADER_EFFECT, OPCODE_EFFECT_ARGS, 0x00, 0x00,
756+
10, HEADER_SET, OPCODE_EFFECT_ARGS, 0x00, 0x00,
722757
(unsigned char) effect->effect, effect->speed, effect->direction,
723758
effect->amount, 0xFF, 0xFF);
724759
unsigned char i;
@@ -747,7 +782,7 @@ int libmk_get_firmware_version(LibMK_Handle* handle, LibMK_Firmware** fw) {
747782
(*fw) = (LibMK_Firmware*) malloc(sizeof(LibMK_Firmware));
748783
for (unsigned char i=0; i<5; i++)
749784
(*fw)->string[i] = p[0x04 + i];
750-
(*fw)->string[5] = (char) NULL;
785+
(*fw)->string[5] = 0x00;
751786
(*fw)->major = p[0x04] & 0x0F;
752787
(*fw)->minor = p[0x06] & 0x0F;
753788
(*fw)->patch = p[0x08] & 0x0F;
@@ -761,8 +796,14 @@ int libmk_save_profile(LibMK_Handle* handle) {
761796
handle = DeviceHandle;
762797
if (handle == NULL)
763798
return LIBMK_ERR_DEV_NOT_SET;
764-
unsigned char* p = libmk_build_packet(2, 0x55, 0x50);
765-
return libmk_send_packet(handle, p);
799+
int r = libmk_set_control_mode(handle, LIBMK_PROFILE_CTRL);
800+
if (r != LIBMK_SUCCESS)
801+
return r;
802+
unsigned char* p = libmk_build_packet(2, 0x50, 0x55);
803+
r = libmk_send_recv_packet(handle, p, false);
804+
if (r != LIBMK_SUCCESS)
805+
return r;
806+
return libmk_set_control_mode(handle, LIBMK_CUSTOM_CTRL);
766807
}
767808

768809

@@ -771,10 +812,16 @@ int libmk_set_active_profile(LibMK_Handle* handle, char profile) {
771812
handle = DeviceHandle;
772813
if (handle == NULL)
773814
return LIBMK_ERR_DEV_NOT_SET;
815+
int r = libmk_set_control_mode(handle, LIBMK_PROFILE_CTRL);
816+
if (r != LIBMK_SUCCESS)
817+
return r;
774818
if (!(1 <= profile <= 4))
775819
return LIBMK_ERR_INVALID_ARG;
776-
unsigned char* p = libmk_build_packet(4, 0x51, 0x00, 0x00, profile);
777-
return libmk_send_packet(handle, p);
820+
unsigned char* p = libmk_build_packet(5, HEADER_SET, 0x00, 0x00, 0x00, profile);
821+
r = libmk_send_packet(handle, p);
822+
if (r != LIBMK_SUCCESS)
823+
return r;
824+
return libmk_set_control_mode(handle, LIBMK_CUSTOM_CTRL);
778825
}
779826

780827

@@ -787,7 +834,17 @@ int libmk_get_active_profile(LibMK_Handle* handle, char* profile) {
787834
int r = libmk_exch_packet(handle, p);
788835
if (r != LIBMK_SUCCESS)
789836
return r;
790-
*profile = p[3];
837+
*profile = p[4];
791838
free(p);
792839
return LIBMK_SUCCESS;
793840
}
841+
842+
843+
int libmk_set_control_mode(LibMK_Handle* handle, LibMK_ControlMode mode) {
844+
if (handle == NULL)
845+
handle = DeviceHandle;
846+
if (handle == NULL)
847+
return LIBMK_ERR_DEV_NOT_SET;
848+
char* p = libmk_build_packet(2, 0x41, mode);
849+
return libmk_send_recv_packet(handle, p, false);
850+
}

libmk/libmk.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ int libmk_get_firmware_version(LibMK_Handle* handle, LibMK_Firmware** fw);
325325
int libmk_set_active_profile(LibMK_Handle* handle, char profile);
326326
int libmk_get_active_profile(LibMK_Handle* handle, char* profile);
327327
int libmk_save_profile(LibMK_Handle* handle);
328+
<<<<<<< HEAD
328329
>>>>>>> ce36524... Fix libmk_create_handle
329330

330331
/** @brief Retrieve details on the firmware version of the device
@@ -336,6 +337,9 @@ int libmk_save_profile(LibMK_Handle* handle);
336337
* @returns LibMK_Result result code, NULL or LibMK_Firmware* in fw
337338
*/
338339
int libmk_get_firmware_version(LibMK_Handle* handle, LibMK_Firmware** fw);
340+
=======
341+
int libmk_set_control_mode(LibMK_Handle* handle, LibMK_ControlMode mode);
342+
>>>>>>> 748c903... Fix errors during profile control
339343

340344
/** @brief Send a single packet and verify the response
341345
*
@@ -351,6 +355,11 @@ int libmk_get_firmware_version(LibMK_Handle* handle, LibMK_Firmware** fw);
351355
* pointer.
352356
*/
353357
int libmk_send_packet(LibMK_Handle* handle, unsigned char* packet);
358+
<<<<<<< HEAD
359+
=======
360+
int libmk_send_recv_packet(LibMK_Handle* handle, unsigned char* packet, bool r);
361+
unsigned char* libmk_build_packet(unsigned char predef, ...);
362+
>>>>>>> 748c903... Fix errors during profile control
354363

355364
/** @brief Exchange a single packet with the keyboard
356365
*

utils/main.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
*/
66
#include "../libmk/libmk.h"
77
#include <stdio.h>
8+
#include <stdlib.h>
89
#include <unistd.h>
910
#include "libusb.h"
1011

1112

13+
int max(int a, int b) {
14+
return a > b ? a : b;
15+
}
16+
17+
1218
int main(void) {
1319
/** Run some tests on the masterkeys library */
1420
bool c = libmk_init();
@@ -20,7 +26,7 @@ int main(void) {
2026
int n = libmk_detect_devices(&models);
2127
printf("Detected %d devices.\n", n);
2228
for (int i = 0; i < n; i++) {
23-
printf(" Detected device: %d, %s\n", models[i], LIBMK_MODEL_STRINGS[i]);
29+
printf("Detected device: %d, %s\n", models[i], LIBMK_MODEL_STRINGS[i]);
2430

2531
printf(" Enabling device... ");
2632
int r = libmk_set_device(models[i], NULL);
@@ -50,6 +56,14 @@ int main(void) {
5056
} else
5157
printf("Failed: %d.\n", r);
5258

59+
char profile;
60+
printf(" Retrieving active profile... ");
61+
r = libmk_get_active_profile(NULL, &profile);
62+
if (r == LIBMK_SUCCESS)
63+
printf("Done: %d.\n", profile);
64+
else
65+
printf("Failed: %d.\n", r);
66+
5367
printf(" Setting full color... ");
5468
r = libmk_set_full_color(NULL, 255, 255, 0);
5569
if (r != LIBMK_SUCCESS)
@@ -65,15 +79,27 @@ int main(void) {
6579
else
6680
printf("Done.\n");
6781
sleep(2);
82+
83+
printf(" Setting active profile... ");
84+
r = libmk_set_active_profile(NULL, 4);
85+
if (r != LIBMK_SUCCESS)
86+
printf("Failed: %d.\n", r);
87+
else
88+
printf("Done.\n");
89+
90+
printf(" Retrieving active profile... ");
91+
r = libmk_get_active_profile(NULL, &profile);
92+
if (r == LIBMK_SUCCESS)
93+
printf("Done: %d.\n", profile);
94+
else
95+
printf("Failed: %d.\n", r);
6896

69-
int color = 200;
7097
unsigned char colors[LIBMK_MAX_ROWS][LIBMK_MAX_COLS][3] = {0};
7198
for (short row=0; row < LIBMK_MAX_ROWS; row++)
7299
for (short col=0; col < LIBMK_MAX_COLS; col++) {
73-
color += 8;
74-
colors[row][col][(color / 256 + 1) % 3] = 0xFF -(color % 256);
75-
colors[row][col][(color / 256) % 3] = 0xFF - (color % 128);
76-
colors[row][col][(color / 256 + 2) % 3] = 0xFF - (color % 64);
100+
colors[row][col][0] = 0;
101+
colors[row][col][1] = 50 * row;
102+
colors[row][col][2] = 200;
77103
}
78104
printf(" Setting LED pattern... ");
79105
r = libmk_set_all_led_color(NULL, (unsigned char*) colors);
@@ -82,22 +108,21 @@ int main(void) {
82108
else
83109
printf("Done.\n");
84110
sleep(4);
85-
86-
printf(" Setting single LED... ");
87-
r = libmk_set_single_led(NULL, 0, 0, 255, 255, 0);
111+
112+
printf(" Saving to profile %d... ", profile);
113+
r = libmk_save_profile(NULL);
88114
if (r == LIBMK_SUCCESS)
89115
printf("Done.\n");
90116
else
91117
printf("Failed: %d.\n", r);
92-
sleep(2);
93118

94-
printf(" Retrieving active profile. ");
95-
char profile;
96-
r = libmk_get_active_profile(NULL, &profile);
119+
printf(" Setting single LED... ");
120+
r = libmk_set_single_led(NULL, 0, 0, 255, 255, 0);
97121
if (r == LIBMK_SUCCESS)
98-
printf("Done.\n Profile: %d.\n", profile);
122+
printf("Done.\n");
99123
else
100124
printf("Failed: %d.\n", r);
125+
sleep(2);
101126

102127
printf(" Disabling LED control... ");
103128
r = libmk_disable_control(NULL);
@@ -106,8 +131,7 @@ int main(void) {
106131
else
107132
printf("Done.\n");
108133
libmk_reset(NULL);
109-
110-
libmk_exit();
111134
}
135+
libmk_exit();
112136
return 0;
113137
}

0 commit comments

Comments
 (0)