1- /**
2- * Author: RedFantom
1+ /** Author: RedFantom
32 * License: GNU GPLv3
43 * Copyright (c) 2018-2019 RedFantom
54*/
1110#include <stdio.h>
1211#include <stdlib.h>
1312
14- #define LIBMK_DEBUG
13+ // #define LIBMK_DEBUG
1514// #define LIBMK_USB_DEBUG
1615
1716#ifndef LIBMK_DEBUG
@@ -41,12 +40,11 @@ typedef enum LibMK_Effect LibMK_Effect;
4140typedef struct LibMK_Device LibMK_Device ;
4241
4342/** Constants */
44- const unsigned char HEADER_DEFAULT = 0x41 ; // 0100 0001
45- const unsigned char HEADER_EFFECT = 0x50 ; // 0101 0000
43+ const unsigned char HEADER_SET = 0x51 ; // 1001 0001
44+ const unsigned char HEADER_GET = 0x52 ; // 1001 0010
45+
4646const unsigned char HEADER_FULL_COLOR = 0xc0 ; // 1100 0000
4747const 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
5048const unsigned char OPCODE_EFFECT = 0x28 ; // 0010 1000
5149const unsigned char OPCODE_ALL_LED = 0xA8 ; // 1010 1000
5250const unsigned char OPCODE_EFFECT_ARGS = 0x2c ; // 0010 1100
@@ -59,6 +57,17 @@ const unsigned int ISO[] =
5957const unsigned char LAYOUT_ANSI = 0 ;
6058const unsigned char LAYOUT_ISO = 1 ;
6159
60+ const char * LIBMK_MODEL_STRINGS [] = {
61+ "MasterKeys Pro L RGB" ,
62+ "MasterKeys Pro S RGB" ,
63+ "MasterKeys Pro L White" ,
64+ "MasterKeys Pro M White" ,
65+ "Unknown Model" ,
66+ "MasterKeys Pro M RGB" ,
67+ "Unknown Model" ,
68+ "MasterKeys Pro S White" ,
69+ };
70+
6271/** Layout matrices
6372 *
6473 * These matrices describe the internal addresses of keys within the
@@ -174,7 +183,7 @@ bool libmk_init(void) {
174183#ifdef LIBMK_USB_DEBUG
175184 libusb_set_debug (Context , LIBUSB_LOG_LEVEL_DEBUG );
176185#endif
177- return (result == 0 );
186+ return (result == LIBUSB_SUCCESS );
178187}
179188
180189
@@ -330,13 +339,6 @@ int libmk_create_handle(LibMK_Handle** handle, LibMK_Device* device) {
330339 libusb_close ((* handle )-> handle );
331340 return LIBMK_ERR_UNKNOWN_LAYOUT ;
332341 }
333- LibMK_Firmware * fw ;
334- r = libmk_get_firmware_version (* handle , & fw );
335- if (r != LIBMK_SUCCESS ) {
336- libusb_close ((* handle )-> handle );
337- return r ;
338- }
339- (* handle )-> layout = fw -> layout ;
340342 return LIBMK_SUCCESS ;
341343}
342344
@@ -458,20 +460,17 @@ int libmk_enable_control(LibMK_Handle* handle) {
458460
459461
460462int libmk_send_control_packet (LibMK_Handle * handle ) {
461- unsigned char * disable = libmk_build_packet (
462- 2 , 0x41 , 0x01 );
463- int r = libmk_send_packet (handle , disable );
463+ int r = libmk_set_control_mode (handle , LIBMK_CUSTOM_CTRL );
464464 if (r != LIBMK_SUCCESS )
465465 return r ;
466- unsigned char * packet = libmk_build_packet (
467- 2 , HEADER_DEFAULT , OPCODE_ENABLE );
468- return libmk_send_packet (handle , packet );
469- }
470-
471-
472- int libmk_send_flush_packet (LibMK_Handle * handle ) {
473- unsigned char * packet = libmk_build_packet (2 , 0x50 , 0x55 );
474- return libmk_send_packet (handle , packet );
466+ LibMK_Firmware * fw ;
467+ r = libmk_get_firmware_version (handle , & fw );
468+ if (r != LIBMK_SUCCESS ) {
469+ libusb_close (handle -> handle );
470+ return r ;
471+ }
472+ handle -> layout = fw -> layout ;
473+ return LIBMK_SUCCESS ;
475474}
476475
477476
@@ -481,11 +480,7 @@ int libmk_disable_control(LibMK_Handle* handle) {
481480 if (handle == NULL )
482481 return LIBMK_ERR_DEV_NOT_SET ;
483482
484- int r ;
485-
486- unsigned char * packet = libmk_build_packet (
487- 2 , HEADER_DEFAULT , OPCODE_DISABLE );
488- r = libmk_send_packet (handle , packet );
483+ int r = libmk_set_control_mode (handle , LIBMK_FIRMWARE_CTRL );
489484 if (r != LIBMK_SUCCESS )
490485 return r ;
491486
@@ -538,12 +533,8 @@ int libmk_set_effect(LibMK_Handle* handle, LibMK_Effect effect) {
538533 if (r != LIBMK_SUCCESS )
539534 return r ;
540535 packet = libmk_build_packet (
541- 5 , HEADER_DEFAULT | HEADER_EFFECT , OPCODE_EFFECT ,
542- 0x00 , 0x00 , (unsigned char ) effect );
543- r = libmk_send_packet (handle , packet );
544- if (r != LIBMK_SUCCESS )
545- return r ;
546- return libmk_send_flush_packet (handle );
536+ 5 , HEADER_SET , OPCODE_EFFECT , 0x00 , 0x00 , (unsigned char ) effect );
537+ return libmk_send_packet (handle , packet );
547538}
548539
549540
@@ -562,24 +553,40 @@ int libmk_set_full_color(LibMK_Handle* handle,
562553
563554
564555int libmk_send_packet (LibMK_Handle * handle , unsigned char * packet ) {
556+ return libmk_send_recv_packet (handle , packet , true);
557+ }
558+
559+
560+ int libmk_send_recv_packet (
561+ LibMK_Handle * handle , unsigned char * packet , bool response_required ) {
562+ if (handle == NULL )
563+ handle = DeviceHandle ;
564+ if (handle == NULL )
565+ return LIBMK_ERR_DEV_NOT_SET ;
565566 int t , result ;
566567 int r = libusb_interrupt_transfer (
567568 handle -> handle , LIBMK_EP_OUT | LIBUSB_ENDPOINT_OUT ,
568569 packet , LIBMK_PACKET_SIZE , & t ,
569570 LIBMK_PACKET_TIMEOUT );
571+ #ifdef LIBMK_DEBUG
572+ libmk_print_packet (packet , "Sent" );
573+ #endif // LIBMK_DEBUG
570574 free (packet );
571575 if (r != 0 || t != LIBMK_PACKET_SIZE )
572576 return LIBMK_ERR_TRANSFER ;
573577 packet = libmk_build_packet (0 );
574578 r = libusb_interrupt_transfer (
575579 handle -> handle , LIBMK_EP_IN | LIBUSB_ENDPOINT_IN ,
576580 packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
577- if (r != LIBUSB_SUCCESS ) {
581+ #ifdef LIBMK_DEBUG
582+ libmk_print_packet (packet , "Response" );
583+ #endif // LIBMK_DEBUG
584+ if (r != LIBUSB_SUCCESS && response_required ) {
578585 result = LIBMK_ERR_TRANSFER ;
579- } else if (t != LIBMK_PACKET_SIZE ) {
586+ } else if (t != LIBMK_PACKET_SIZE && response_required ) {
580587 result = LIBMK_ERR_TRANSFER ;
581588 } else if (packet [0 ] == HEADER_ERROR ) {
582- libmk_print_packet (packet );
589+ libmk_print_packet (packet , "Error response" );
583590 result = LIBMK_ERR_PROTOCOL ;
584591 } else
585592 result = LIBMK_SUCCESS ;
@@ -593,13 +600,19 @@ int libmk_exch_packet(LibMK_Handle* handle, unsigned char* packet) {
593600 int r = libusb_interrupt_transfer (
594601 handle -> handle , LIBMK_EP_OUT | LIBUSB_ENDPOINT_OUT ,
595602 packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
603+ #ifdef LIBMK_DEBUG
604+ libmk_print_packet (packet , "Sent" );
605+ #endif // LIBMK_DEBUG
596606 if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE ) {
597607 free (packet );
598608 return LIBMK_ERR_TRANSFER ;
599609 }
600610 r = libusb_interrupt_transfer (
601611 handle -> handle , LIBMK_EP_IN | LIBUSB_ENDPOINT_IN ,
602612 packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
613+ #ifdef LIBMK_DEBUG
614+ libmk_print_packet (packet , "Received" );
615+ #endif // LIBMK_DEBUG
603616 if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE )
604617 return LIBMK_ERR_TRANSFER ;
605618 return LIBMK_SUCCESS ;
@@ -646,9 +659,7 @@ int libmk_set_all_led_color(LibMK_Handle* handle, unsigned char* colors) {
646659 unsigned char * packets [LIBMK_ALL_LED_PCK_NUM ];
647660
648661 for (short i = 0 ; i < LIBMK_ALL_LED_PCK_NUM ; i ++ )
649- packets [i ] = libmk_build_packet (
650- 3 , HEADER_DEFAULT | HEADER_EFFECT ,
651- OPCODE_ALL_LED , (unsigned char ) i * 2 );
662+ packets [i ] = libmk_build_packet (3 , HEADER_SET , 0xA8 , (unsigned char ) i * 2 );
652663
653664 unsigned char offset ;
654665 int packet , index , result ;
@@ -667,23 +678,19 @@ int libmk_set_all_led_color(LibMK_Handle* handle, unsigned char* colors) {
667678 (r * LIBMK_MAX_COLS + c ) * 3 + o ];
668679 }
669680 }
670-
671- int r = libmk_send_flush_packet (handle );
672- if (r != LIBMK_SUCCESS )
673- return r ;
681+
674682 for (short k = 0 ; k < LIBMK_ALL_LED_PCK_NUM ; k ++ ) {
675- r = libmk_send_packet (handle , packets [k ]);
683+ int r = libmk_send_packet (handle , packets [k ]);
676684 if (r != LIBMK_SUCCESS )
677685 return r ;
678686 }
679- unsigned char * flush = libmk_build_packet (2 , 0x50 , 0x55 );
680- return libmk_send_packet (handle , flush );
687+ return LIBMK_SUCCESS ;
681688}
682689
683690
684- inline void libmk_print_packet (unsigned char * packet ) {
691+ inline void libmk_print_packet (unsigned char * packet , char * label ) {
685692#ifdef LIBMK_DEBUG
686- printf ("Packet:\n" );
693+ printf ("Packet: %s \n" , label );
687694 for (unsigned char j = 0 ; j < LIBMK_PACKET_SIZE ; j ++ ) {
688695 printf ("%02x " , packet [j ]);
689696 if ((j + 1 ) % 16 == 0 ) {
@@ -712,7 +719,7 @@ int libmk_set_single_led(
712719 handle = DeviceHandle ;
713720 if (handle == NULL )
714721 return LIBMK_ERR_DEV_NOT_SET ;
715- int result = libmk_send_control_packet (handle );
722+ int result = libmk_set_control_mode (handle , LIBMK_CUSTOM_CTRL );
716723 if (result != LIBMK_SUCCESS )
717724 return result ;
718725 unsigned char offset ;
@@ -732,7 +739,7 @@ int libmk_set_effect_details(
732739 if (handle == NULL )
733740 return LIBMK_ERR_DEV_NOT_SET ;
734741 unsigned char * packet = libmk_build_packet (
735- 10 , HEADER_DEFAULT | HEADER_EFFECT , OPCODE_EFFECT_ARGS , 0x00 , 0x00 ,
742+ 10 , HEADER_SET , OPCODE_EFFECT_ARGS , 0x00 , 0x00 ,
736743 (unsigned char ) effect -> effect , effect -> speed , effect -> direction ,
737744 effect -> amount , 0xFF , 0xFF );
738745 unsigned char i ;
@@ -761,10 +768,69 @@ int libmk_get_firmware_version(LibMK_Handle* handle, LibMK_Firmware** fw) {
761768 (* fw ) = (LibMK_Firmware * ) malloc (sizeof (LibMK_Firmware ));
762769 for (unsigned char i = 0 ; i < 5 ; i ++ )
763770 (* fw )-> string [i ] = p [0x04 + i ];
764- (* fw )-> string [5 ] = ( char ) NULL ;
771+ (* fw )-> string [5 ] = 0x00 ;
765772 (* fw )-> major = p [0x04 ] & 0x0F ;
766773 (* fw )-> minor = p [0x06 ] & 0x0F ;
767774 (* fw )-> patch = p [0x08 ] & 0x0F ;
768775 (* fw )-> layout = p [0x04 ] & 0x0F ;
769776 return LIBMK_SUCCESS ;
770777}
778+
779+
780+ int libmk_save_profile (LibMK_Handle * handle ) {
781+ if (handle == NULL )
782+ handle = DeviceHandle ;
783+ if (handle == NULL )
784+ return LIBMK_ERR_DEV_NOT_SET ;
785+ int r = libmk_set_control_mode (handle , LIBMK_PROFILE_CTRL );
786+ if (r != LIBMK_SUCCESS )
787+ return r ;
788+ unsigned char * p = libmk_build_packet (2 , 0x50 , 0x55 );
789+ r = libmk_send_recv_packet (handle , p , false);
790+ if (r != LIBMK_SUCCESS )
791+ return r ;
792+ return libmk_set_control_mode (handle , LIBMK_CUSTOM_CTRL );
793+ }
794+
795+
796+ int libmk_set_active_profile (LibMK_Handle * handle , char profile ) {
797+ if (handle == NULL )
798+ handle = DeviceHandle ;
799+ if (handle == NULL )
800+ return LIBMK_ERR_DEV_NOT_SET ;
801+ int r = libmk_set_control_mode (handle , LIBMK_PROFILE_CTRL );
802+ if (r != LIBMK_SUCCESS )
803+ return r ;
804+ if (!(1 <= profile <= 4 ))
805+ return LIBMK_ERR_INVALID_ARG ;
806+ unsigned char * p = libmk_build_packet (5 , HEADER_SET , 0x00 , 0x00 , 0x00 , profile );
807+ r = libmk_send_packet (handle , p );
808+ if (r != LIBMK_SUCCESS )
809+ return r ;
810+ return libmk_set_control_mode (handle , LIBMK_CUSTOM_CTRL );
811+ }
812+
813+
814+ int libmk_get_active_profile (LibMK_Handle * handle , char * profile ) {
815+ if (handle == NULL )
816+ handle = DeviceHandle ;
817+ if (handle == NULL )
818+ return LIBMK_ERR_DEV_NOT_SET ;
819+ unsigned char * p = libmk_build_packet (1 , 0x52 );
820+ int r = libmk_exch_packet (handle , p );
821+ if (r != LIBMK_SUCCESS )
822+ return r ;
823+ * profile = p [4 ];
824+ free (p );
825+ return LIBMK_SUCCESS ;
826+ }
827+
828+
829+ int libmk_set_control_mode (LibMK_Handle * handle , LibMK_ControlMode mode ) {
830+ if (handle == NULL )
831+ handle = DeviceHandle ;
832+ if (handle == NULL )
833+ return LIBMK_ERR_DEV_NOT_SET ;
834+ char * p = libmk_build_packet (2 , 0x41 , mode );
835+ return libmk_send_recv_packet (handle , p , false);
836+ }
0 commit comments