Skip to content

Commit 80410d9

Browse files
committed
Fix issues with LibMK_Controller
1 parent 05daa17 commit 80410d9

File tree

6 files changed

+133
-72
lines changed

6 files changed

+133
-72
lines changed

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
cmake_minimum_required(VERSION 3.9)
55
set(CMAKE_C_FLAGS "-std=c99")
66
include(libmk/CMakeLists.txt)
7-
include(libmkc/CMakeLists.txt)
87
if (SKBUILD) # The masterkeys package can only be built with scikit-build
98
include(masterkeys/CMakeLists.txt)
109
endif()

libmk/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,16 @@ include_directories(${LIBUSB_INCLUDE_DIR})
1616
install(TARGETS mk
1717
LIBRARY DESTINATION lib
1818
PUBLIC_HEADER DESTINATION include)
19+
20+
add_library(mkc SHARED libmk/libmkc.c)
21+
set_target_properties(mkc PROPERTIES
22+
VERSION ${PROJECT_VERSION}
23+
PUBLIC_HEADER libmk/libmkc.h
24+
PREFIX "")
25+
target_link_libraries(mk usb-1.0)
26+
include_directories(${LIBUSB_INCLUDE_DIR})
27+
28+
install(TARGETS mkc
29+
LIBRARY DESTINATION lib
30+
PUBLIC_HEADER DESTINATION include)
31+

libmkc/libmkc.c renamed to libmk/libmkc.c

Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@
77
#include <pthread.h>
88
#include <stdlib.h>
99
#include <time.h>
10+
#include <unistd.h>
1011

11-
12-
void sleep (double t) {
13-
/** Sleep for a specified amount of seconds */
14-
clock_t start = clock();
15-
while(((double) (clock() - start)) / CLOCKS_PER_SEC < t);
16-
}
12+
#define LIBMKC_DEBUG
1713

1814

1915
LibMK_Controller* libmk_create_controller(LibMK_Handle* handle) {
@@ -27,13 +23,17 @@ LibMK_Controller* libmk_create_controller(LibMK_Handle* handle) {
2723
pthread_mutex_init(&controller->exit_flag_lock, NULL);
2824
pthread_mutex_init(&controller->instr_lock, NULL);
2925
pthread_mutex_init(&controller->error_lock, NULL);
26+
controller->instr = NULL;
27+
controller->state = LIBMK_STATE_PRESTART;
28+
controller->exit_flag = false;
29+
controller->wait_flag = false;
3030
return controller;
3131
}
3232

3333

3434
LibMK_Controller_State libmk_get_controller_state(LibMK_Controller* c) {
3535
/** Return whether the given controller is running (active) */
36-
pthread_mutex_lock(&c->state_lock);
36+
pthread_mutex_lock(&(c->state_lock));
3737
LibMK_Controller_State b = c->state;
3838
pthread_mutex_unlock(&c->state_lock);
3939
return b;
@@ -42,9 +42,9 @@ LibMK_Controller_State libmk_get_controller_state(LibMK_Controller* c) {
4242

4343
LibMK_Result libmk_get_controller_error(LibMK_Controller* c) {
4444
/** Return an error if the controller has one set */
45-
pthread_mutex_lock(&c->error_lock);
45+
pthread_mutex_lock(&(c->error_lock));
4646
LibMK_Result r = c->error;
47-
pthread_mutex_unlock(&c->error_lock);
47+
pthread_mutex_unlock(&(c->error_lock));
4848
return r;
4949
}
5050

@@ -80,69 +80,83 @@ LibMK_Result libmk_start_controller(LibMK_Controller* controller) {
8080

8181
void libmk_run_controller(LibMK_Controller* controller) {
8282
/** Execute instructions on a LibMK_Controller in a separate thread */
83-
bool exit_flag;
83+
pthread_mutex_lock(&(controller->state_lock));
84+
controller->state = LIBMK_STATE_ACTIVE;
85+
pthread_mutex_unlock(&(controller->state_lock));
86+
bool exit_flag, wait_flag;
8487
while (true) {
85-
pthread_mutex_lock(&controller->exit_flag_lock);
88+
pthread_mutex_lock(&(controller->exit_flag_lock));
8689
exit_flag = controller->exit_flag;
87-
pthread_mutex_unlock(&controller->exit_flag_lock);
90+
wait_flag = controller->wait_flag;
91+
pthread_mutex_unlock(&(controller->exit_flag_lock));
8892
if (exit_flag)
8993
break;
90-
91-
if (controller->instr == NULL)
94+
pthread_mutex_lock(&(controller->instr_lock));
95+
if (controller->instr == NULL) {
96+
pthread_mutex_unlock(&(controller->instr_lock));
97+
if (wait_flag)
98+
break;
99+
usleep(1000);
92100
continue;
101+
}
93102
LibMK_Result r = (LibMK_Result) libmk_exec_instruction(
94103
controller->handle, controller->instr);
95104
if (r != LIBMK_SUCCESS) {
96105
libmk_set_controller_error(controller, r);
106+
pthread_mutex_unlock(&(controller->instr_lock));
97107
break;
98108
}
99-
// Sleep
100-
struct timespec delay;
101-
delay.tv_nsec = controller->instr->duration;
102-
nanosleep(&delay, NULL);
109+
usleep(controller->instr->duration);
103110
// Move on to next instruction
104111
LibMK_Instruction* old = controller->instr;
105112
controller->instr = controller->instr->next;
106113
libmk_free_instruction(old);
114+
pthread_mutex_unlock(&(controller->instr_lock));
107115
}
108116
int r = libmk_disable_control(controller->handle);
109117
if (r != LIBMK_SUCCESS) {
110118
libmk_set_controller_error(controller, (LibMK_Result) r);
111119
}
120+
pthread_mutex_lock(&(controller->state_lock));
121+
controller->state = LIBMK_STATE_STOPPED;
122+
pthread_mutex_unlock(&(controller->state_lock));
112123
}
113124

114125

115126
void libmk_set_controller_error(LibMK_Controller* c, LibMK_Result e) {
116127
/** Set an error in the controller struct if one has not been set */
117-
pthread_mutex_lock(&c->error_lock);
128+
pthread_mutex_lock(&(c->error_lock));
118129
if (c->error == LIBMK_SUCCESS)
119130
c->error = e;
120-
pthread_mutex_unlock(&c->error_lock);
131+
pthread_mutex_unlock(&(c->error_lock));
121132
}
122133

123134

124-
int libmk_exec_instruction(LibMK_Handle* h, LibMK_Instruction* i) {
135+
LibMK_Result libmk_exec_instruction(LibMK_Handle* h, LibMK_Instruction* i) {
125136
/** Execute a single instruction on the keyboard controlled */
126137
if (i == NULL)
127138
return libmk_send_control_packet(h);
128-
else if (i->colors != NULL) {
139+
else if (i->type == LIBMK_INSTR_ALL) {
129140
return libmk_set_all_led_color(h, i->colors);
130-
} else {
131-
unsigned char colors[LIBMK_MAX_ROWS][LIBMK_MAX_COLS][3];
132-
for (unsigned char r = 0; r < LIBMK_MAX_ROWS; r++)
133-
for (unsigned char c = 0; c < LIBMK_MAX_COLS; c++)
134-
for (unsigned char k = 0; k < 3; k++)
135-
colors[r][c][k] = i->color[k];
136-
return libmk_set_all_led_color(h, (unsigned char*) colors);
141+
} else if (i->type == LIBMK_INSTR_FULL) {
142+
return libmk_set_full_color(h, i->color[0], i->color[1], i->color[2]);
137143
}
138144
}
139145

140146

141147
void libmk_stop_controller(LibMK_Controller* controller) {
142148
/** Stop a LibMK_Controller running in a separate thread */
143-
pthread_mutex_lock(&controller->exit_flag_lock);
149+
pthread_mutex_lock(&(controller->exit_flag_lock));
144150
controller->exit_flag = true;
145-
pthread_mutex_unlock(&controller->exit_flag_lock);
151+
pthread_mutex_unlock(&(controller->exit_flag_lock));
152+
}
153+
154+
155+
void libmk_wait_controller(LibMK_Controller* controller) {
156+
/** Set the flag to wait for the controller to finish scheduled instr */
157+
pthread_mutex_lock(&(controller->exit_flag_lock));
158+
controller->wait_flag = true;
159+
pthread_mutex_unlock(&(controller->exit_flag_lock));
146160
}
147161

148162

@@ -153,11 +167,11 @@ LibMK_Controller_State libmk_join_controller(
153167
clock_t t = clock();
154168
double elapsed;
155169
while (true) {
156-
pthread_mutex_lock(&controller->state_lock);
170+
pthread_mutex_lock(&(controller->state_lock));
157171
s = controller->state;
158-
pthread_mutex_unlock(&controller->state_lock);
159-
// if (s != LIBMK_STATE_ACTIVE)
160-
// break;
172+
pthread_mutex_unlock(&(controller->state_lock));
173+
if (s != LIBMK_STATE_ACTIVE)
174+
break;
161175
elapsed = ((double) (clock() - t)) / CLOCKS_PER_SEC;
162176
if (elapsed > timeout)
163177
return LIBMK_STATE_JOIN_ERR;
@@ -168,6 +182,7 @@ LibMK_Controller_State libmk_join_controller(
168182

169183
void libmk_free_instruction(LibMK_Instruction* i) {
170184
/** Free the memory allocated for an executed instruction */
185+
fflush(stdout);
171186
if (i->colors != NULL)
172187
free(i->colors);
173188
free(i);
@@ -180,6 +195,9 @@ LibMK_Instruction* libmk_create_instruction() {
180195
(LibMK_Instruction*) malloc(sizeof(LibMK_Instruction));
181196
i->duration = 0;
182197
i->id = 0;
198+
i->type = -1;
199+
i->next = NULL;
200+
i->colors = NULL;
183201
return i;
184202
}
185203

@@ -189,6 +207,7 @@ LibMK_Instruction* libmk_create_instruction_full(unsigned char c[3]) {
189207
LibMK_Instruction* i = libmk_create_instruction();
190208
for (unsigned char j=0; j<3; j++)
191209
i->color[j] = c[j];
210+
i->type = LIBMK_INSTR_FULL;
192211
return i;
193212
}
194213

@@ -203,14 +222,43 @@ LibMK_Instruction* libmk_create_instruction_all(
203222
for (unsigned char col=0; col<LIBMK_MAX_COLS; col++)
204223
for (unsigned char j=0; j<3; j++)
205224
i->colors[row * LIBMK_MAX_COLS + j] = c[row][col][j];
225+
i->type = LIBMK_INSTR_ALL;
226+
return i;
227+
}
228+
229+
230+
LibMK_Instruction* libmk_create_instruction_flash(
231+
unsigned char c[3], unsigned int delay, unsigned char n) {
232+
unsigned char color[3] = {0};
233+
LibMK_Instruction* i = libmk_create_instruction_full(color);
234+
LibMK_Instruction* k = i;
235+
LibMK_Instruction* l;
236+
for (unsigned char j=0; j<n; j++) {
237+
color[0] = ((double) j / (double) n) * c[0];
238+
color[1] = ((double) j / (double) n) * c[1];
239+
color[2] = ((double) j / (double) n) * c[2];
240+
l = libmk_create_instruction_full(color);
241+
l->duration = delay;
242+
k->next = l;
243+
k = l;
244+
}
245+
for (unsigned char j=n; j>0; j--) {
246+
color[0] = ((double) j / (double) n) * c[0];
247+
color[1] = ((double) j / (double) n) * c[1];
248+
color[2] = ((double) j / (double) n) * c[2];
249+
l = libmk_create_instruction_full(color);
250+
l->duration = delay;
251+
k->next = l;
252+
k = l;
253+
}
206254
return i;
207255
}
208256

209257

210258
LibMK_Result libmk_sched_instruction(
211259
LibMK_Controller* c, LibMK_Instruction* i) {
212260
/** Schedule a single instruction for execution on the controller */
213-
pthread_mutex_lock(&c->instr_lock);
261+
pthread_mutex_lock(&(c->instr_lock));
214262
if (c->instr == NULL) {
215263
c->instr = i;
216264
c->instr->id = 1;
@@ -225,14 +273,23 @@ LibMK_Result libmk_sched_instruction(
225273
t = t->next;
226274
}
227275
}
228-
pthread_mutex_unlock(&c->instr_lock);
276+
if (i->next != NULL) {
277+
LibMK_Instruction *k = i->next;
278+
unsigned int id = i->id;
279+
while (k != NULL) {
280+
id += 1;
281+
k->id = id;
282+
k = k->next;
283+
}
284+
}
285+
pthread_mutex_unlock(&(c->instr_lock));
229286
return LIBMK_SUCCESS;
230287
}
231288

232289

233290
LibMK_Result libmk_cancel_instruction(LibMK_Controller* c, unsigned int id) {
234291
/** Cancel a scheduled instruction from executing */
235-
pthread_mutex_lock(&c->instr_lock);
292+
pthread_mutex_lock(&(c->instr_lock));
236293
LibMK_Instruction* prev = NULL;
237294
LibMK_Instruction* curr = c->instr;
238295
while (curr != NULL) {
@@ -248,6 +305,6 @@ LibMK_Result libmk_cancel_instruction(LibMK_Controller* c, unsigned int id) {
248305
prev = curr;
249306
curr = curr->next;
250307
}
251-
pthread_mutex_unlock(&c->instr_lock);
308+
pthread_mutex_unlock(&(c->instr_lock));
252309
return LIBMK_SUCCESS;
253310
}

libmkc/libmkc.h renamed to libmk/libmkc.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
* License: GNU GPLv3
44
* Copyright (c) 2018 RedFantom
55
*/
6-
#include "../libmk/libmk.h"
6+
#include "libmk.h"
77
#include <pthread.h>
88
#include <stdlib.h>
99
#include <time.h>
10+
#include <unistd.h>
1011

1112

1213
typedef enum LibMK_Controller_State {
@@ -20,6 +21,13 @@ typedef enum LibMK_Controller_State {
2021
} LibMK_Controller_State;
2122

2223

24+
typedef enum LibMK_Instruction_Type {
25+
LIBMK_INSTR_FULL = 0,
26+
LIBMK_INSTR_ALL = 1,
27+
28+
} LibMK_Instruction_Type;
29+
30+
2331
typedef struct LibMK_Instruction {
2432
/** Single instruction that can be executed by a controller
2533
*
@@ -32,6 +40,7 @@ typedef struct LibMK_Instruction {
3240
unsigned int duration;
3341
unsigned int id;
3442
struct LibMK_Instruction* next;
43+
LibMK_Instruction_Type type;
3544
} LibMK_Instruction;
3645

3746

@@ -46,6 +55,7 @@ typedef struct LibMK_Controller {
4655
pthread_t thread;
4756
pthread_mutex_t exit_flag_lock;
4857
bool exit_flag;
58+
bool wait_flag;
4959
pthread_mutex_t state_lock;
5060
LibMK_Controller_State state;
5161
pthread_mutex_t error_lock;
@@ -56,21 +66,22 @@ typedef struct LibMK_Controller {
5666
LibMK_Controller* libmk_create_controller(LibMK_Handle* handle);
5767
LibMK_Result libmk_free_controller(LibMK_Controller* c);
5868

59-
unsigned int libmk_sched_instruction(
69+
LibMK_Result libmk_sched_instruction(
6070
LibMK_Controller* controller, LibMK_Instruction* instruction);
6171
LibMK_Result libmk_cancel_instruction(LibMK_Controller* c, unsigned int id);
6272

6373
LibMK_Result libmk_start_controller(LibMK_Controller* controller);
6474
void libmk_run_controller(LibMK_Controller* controller);
6575
void libmk_stop_controller(LibMK_Controller* controller);
76+
void libmk_wait_controller(LibMK_Controller* controller);
6677
LibMK_Controller_State libmk_join_controller(LibMK_Controller* c, double t);
6778
void libmk_set_controller_error(LibMK_Controller* c, LibMK_Result r);
6879

6980
LibMK_Instruction* libmk_create_instruction();
7081
LibMK_Instruction* libmk_create_instruction_full(unsigned char c[3]);
7182
LibMK_Instruction* libmk_create_instruction_all(
7283
unsigned char c[LIBMK_MAX_ROWS][LIBMK_MAX_COLS][3]);
84+
LibMK_Instruction* libmk_create_instruction_flash(unsigned char c[3], unsigned int delay, unsigned char n);
7385
void libmk_free_instruction(LibMK_Instruction* i);
7486

75-
76-
int libmk_exec_instruction(LibMK_Handle* h, LibMK_Instruction* i);
87+
LibMK_Result libmk_exec_instruction(LibMK_Handle* h, LibMK_Instruction* i);

libmkc/CMakeLists.txt

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)