@@ -27,11 +27,14 @@ PatriotViperController::PatriotViperController(i2c_smbus_interface* bus, viper_d
27
27
led_count += 5 ;
28
28
}
29
29
}
30
+
31
+ keepalive_thread = NULL ;
32
+ keepalive_thread_run = 1 ;
30
33
}
31
34
32
35
PatriotViperController::~PatriotViperController ()
33
36
{
34
-
37
+ StopKeepaliveThread ();
35
38
}
36
39
37
40
std::string PatriotViperController::GetDeviceName ()
@@ -92,26 +95,16 @@ void PatriotViperController::SetEffectColor(unsigned char red, unsigned char gre
92
95
93
96
void PatriotViperController::SetAllColors (unsigned char red, unsigned char green, unsigned char blue)
94
97
{
95
- ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
96
- ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
97
-
98
- ViperRegisterWrite (VIPER_REG_LED0_DIRECT_COLOR, red, blue, green);
99
- ViperRegisterWrite (VIPER_REG_LED1_DIRECT_COLOR, red, blue, green);
100
- ViperRegisterWrite (VIPER_REG_LED2_DIRECT_COLOR, red, blue, green);
101
- ViperRegisterWrite (VIPER_REG_LED3_DIRECT_COLOR, red, blue, green);
102
- ViperRegisterWrite (VIPER_REG_LED4_DIRECT_COLOR, red, blue, green);
103
-
104
- ViperRegisterWrite (VIPER_REG_APPLY, 0x01 , 0x00 , 0x00 );
98
+ ViperRegisterWrite (VIPER_REG_LED0_EFFECT_COLOR, red, blue, green);
99
+ ViperRegisterWrite (VIPER_REG_LED1_EFFECT_COLOR, red, blue, green);
100
+ ViperRegisterWrite (VIPER_REG_LED2_EFFECT_COLOR, red, blue, green);
101
+ ViperRegisterWrite (VIPER_REG_LED3_EFFECT_COLOR, red, blue, green);
102
+ ViperRegisterWrite (VIPER_REG_LED4_EFFECT_COLOR, red, blue, green);
105
103
}
106
104
107
105
void PatriotViperController::SetLEDColor (unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
108
106
{
109
- ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
110
- ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
111
-
112
- ViperRegisterWrite (VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
113
-
114
- ViperRegisterWrite (VIPER_REG_APPLY, 0x01 , 0x00 , 0x00 );
107
+ ViperRegisterWrite (VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
115
108
}
116
109
117
110
void PatriotViperController::SetLEDEffectColor (unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
@@ -148,29 +141,198 @@ void PatriotViperController::SetLEDEffectColor(unsigned int /*slot*/, unsigned i
148
141
ViperRegisterWrite (VIPER_REG_MODE, 0xFA , 0x00 , 0x00 );
149
142
}
150
143
151
- void PatriotViperController::SetMode (unsigned char new_mode, unsigned char new_speed)
144
+ void PatriotViperController::SetMode (unsigned char new_mode, unsigned char new_speed, unsigned int color_mode )
152
145
{
146
+ StopKeepaliveThread ();
153
147
direct = false ;
154
148
mode = new_mode;
155
- speed = new_speed;
149
+ if (mode_speed[mode] == -1 )
150
+ {
151
+ speed = new_speed;
152
+ }
153
+ else
154
+ {
155
+ speed = mode_speed[mode];
156
+ }
156
157
157
- ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
158
- ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
159
- ViperRegisterWrite (VIPER_REG_MODE, mode, 0x00 , speed);
160
- ViperRegisterWrite (VIPER_REG_MODE, 0xAA , 0x00 , 0x00 );
161
- ViperRegisterWrite (VIPER_REG_MODE, 0xFA , 0x00 , 0x00 );
158
+ if (color_mode == 3 )
159
+ {
160
+ /* --------------------------------------------------------------------------------------------------*\
161
+ | Reset previously set mode color, because we want RAM sticks to fall-back to automatic viper colors |
162
+ | These are not just rainbowey, but they are affected differently with modes. |
163
+ \*--------------------------------------------------------------------------------------------------*/
164
+
165
+ ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
166
+ ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
167
+ ViperRegisterWrite (VIPER_REG_MODE, VIPER_MODE_DARK, 0x00 , 0x00 );
168
+ ViperRegisterWrite (VIPER_REG_MODE, 0xAA , 0x00 , 0x00 );
169
+ ViperRegisterWrite (VIPER_REG_MODE, 0xFA , 0x00 , 0x00 );
170
+ }
171
+
172
+ if (mode_steps[mode] == -1 )
173
+ {
174
+ /* --------------------------------------------------------------------------------------------------*\
175
+ | Based on a header file, if number of steps in mode is -1 it means mode is not synced, |
176
+ | doesn't have steps and the Keepalive thread is not needed. Set the mode directly and leave it. |
177
+ \*--------------------------------------------------------------------------------------------------*/
178
+
179
+ ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
180
+ ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
181
+ ViperRegisterWrite (VIPER_REG_MODE, mode, 0x00 , speed);
182
+ ViperRegisterWrite (VIPER_REG_MODE, 0xAA , 0x00 , 0x00 );
183
+ ViperRegisterWrite (VIPER_REG_MODE, 0xFA , 0x00 , 0x00 );
184
+ }
185
+ else
186
+ {
187
+ /* ----------------------------------------------------------------*\
188
+ | Reset step counters and fire up Keepalive thread. |
189
+ | Thread will deal with changing the mode and everything else. |
190
+ \*----------------------------------------------------------------*/
191
+
192
+ step = 0 ;
193
+ sub_step = 0 ;
194
+
195
+ keepalive_thread = new std::thread (&PatriotViperController::KeepaliveThread, this );
196
+ }
162
197
}
163
198
164
199
void PatriotViperController::SetDirect ()
165
200
{
201
+ StopKeepaliveThread ();
166
202
direct = true ;
167
203
ViperRegisterWrite (VIPER_REG_START, 0xFF , 0xFF , 0xFF );
168
204
ViperRegisterWrite (VIPER_REG_STATIC, 0x04 , 0x00 , 0x00 );
169
- ViperRegisterWrite (VIPER_REG_APPLY, 0x01 , 0x00 , 0x00 );
205
+ ViperRegisterWrite (VIPER_REG_MODE, VIPER_MODE_DIRECT , 0x00 , 0x00 );
170
206
}
171
207
172
208
void PatriotViperController::ViperRegisterWrite (viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2)
173
209
{
174
210
bus->i2c_smbus_write_byte_data (dev, reg, val0);
175
211
bus->i2c_smbus_write_byte_data (dev, val2, val1);
176
212
}
213
+
214
+ void PatriotViperController::KeepaliveThread ()
215
+ {
216
+ while (keepalive_thread_run.load ())
217
+ {
218
+ int cur_step = step.load ();
219
+ int cur_sub_step = sub_step.load ();
220
+ if (cur_sub_step == 0 )
221
+ {
222
+ ViperRegisterWrite (VIPER_REG_MODE, mode, cur_step, speed);
223
+ ViperRegisterWrite (VIPER_REG_MODE, 0xAA , 0x00 , cur_sub_step);
224
+ }
225
+ else
226
+ {
227
+ ViperRegisterWrite (VIPER_REG_MODE, 0xAA , 0x00 , cur_sub_step);
228
+ }
229
+
230
+ if (cur_sub_step == mode_sub_steps[mode])
231
+ {
232
+ sub_step.store (0 );
233
+
234
+ if (cur_step == mode_steps[mode])
235
+ {
236
+ step.store (0 );
237
+ }
238
+ else
239
+ {
240
+ step.store (cur_step+1 );
241
+ }
242
+ }
243
+ else
244
+ {
245
+ sub_step.store (cur_sub_step+1 );
246
+ }
247
+
248
+ /* ---------------------------------------------------------------------------------------------------------*\
249
+ | We have to use wait_for with condition_variable since some of the modes will keep the thread waiting for |
250
+ | long time and we don't want to make user wait for mode change when in middle of waiting period. |
251
+ \*---------------------------------------------------------------------------------------------------------*/
252
+ int delay = GetDelay (mode, cur_step, cur_sub_step, cur_sub_step == mode_sub_steps[mode]);
253
+ std::unique_lock<std::mutex> l (thread_ctrl_m);
254
+ thread_ctrl.wait_for (l, std::chrono::milliseconds (delay));
255
+ }
256
+ }
257
+
258
+ void PatriotViperController::StopKeepaliveThread ()
259
+ {
260
+ if (keepalive_thread != NULL )
261
+ {
262
+ keepalive_thread_run = 0 ;
263
+ thread_ctrl.notify_one ();
264
+ keepalive_thread->join ();
265
+ keepalive_thread = NULL ;
266
+ keepalive_thread_run = 1 ;
267
+ }
268
+ }
269
+
270
+ unsigned int PatriotViperController::GetDelay (unsigned char mode, unsigned int step, unsigned int sub_step, bool loop_end)
271
+ {
272
+ if (loop_end)
273
+ {
274
+ if (mode == VIPER_MODE_VIPER)
275
+ {
276
+ return 7000 ;
277
+ }
278
+ else if (mode == VIPER_MODE_BREATHING)
279
+ {
280
+ return 3000 ;
281
+ }
282
+ else if (mode == VIPER_MODE_NEON)
283
+ {
284
+ return 600 ;
285
+ }
286
+ else if (mode == VIPER_MODE_AURORA)
287
+ {
288
+ return 300 ;
289
+ }
290
+ else
291
+ {
292
+ return 0 ;
293
+ }
294
+ }
295
+
296
+ if (sub_step == 0 )
297
+ {
298
+ if (mode == VIPER_MODE_VIPER)
299
+ {
300
+ return 3000 ;
301
+ }
302
+ else if (mode == VIPER_MODE_BREATHING)
303
+ {
304
+ return 3000 ;
305
+ }
306
+ else
307
+ {
308
+ return 0 ;
309
+ }
310
+ }
311
+ else
312
+ {
313
+ if (sub_step == 4 && mode == VIPER_MODE_VIPER)
314
+ {
315
+ return 1000 ;
316
+ }
317
+ else if (sub_step == 5 && mode == VIPER_MODE_VIPER)
318
+ {
319
+ return 590 ;
320
+ }
321
+ else if (mode == VIPER_MODE_NEON)
322
+ {
323
+ return 600 ;
324
+ }
325
+ else if (mode == VIPER_MODE_HEARTBEAT)
326
+ {
327
+ return 100 ;
328
+ }
329
+ else if (mode == VIPER_MODE_MARQUEE)
330
+ {
331
+ return 300 ;
332
+ }
333
+ else
334
+ {
335
+ return 0 ;
336
+ }
337
+ }
338
+ }
0 commit comments