-
Notifications
You must be signed in to change notification settings - Fork 1
/
ChrisBlasterWindowsHost.cpp
878 lines (828 loc) · 30.8 KB
/
ChrisBlasterWindowsHost.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
/**
*
* @author Chris Hall
* <p>
* This program is a DLL designed to allow for other programs to control the
* ChrisBlaster FPGA timing controller. It uses DPCUTIL.DLL from Digilent Inc.
* for the USB I/O.
*
* */
#using <mscorlib.dll>
#pragma unmanaged
#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32)
#define LIBEXPORT __declspec(dllexport)
#define LIBCALL __stdcall
#else
#define LIBEXPORT
#define LIBCALL
#endif
#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32)
#include <Windows.h>
#define CROSSPLATSLEEP(w) Sleep(w)
#else
#include <unistd.h>
#define CROSSPLATSLEEP(w) usleep(w * 1000)
#endif
// Note: HANDLE defined in winnt.h as "typedef void *HANDLE;"
//// includes
#include "chrisblaster_ChrisBlasterManager.h"
#include "ChrisBlasterHost.h"
#include "CBlasterOS.h"
#include "dpcdefs.h"
#include "dpcutil.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
/*
LIBEXPORT return_type LIBCALL function_name(parameters)
* */
#ifdef __cplusplus
extern "C" {
#endif
// Function Declarations go here:
LIBEXPORT void LIBCALL getErrorMessage(char* msgbuff, int length);
LIBEXPORT string LIBCALL errorCodeToMessage(int code);
LIBEXPORT bool LIBCALL initDrivers();
LIBEXPORT bool LIBCALL openChrisBlasterConnection(char* name, HANDLE* devpointer);
LIBEXPORT bool LIBCALL closeChrisBlasterConnection(HANDLE devpointer);
LIBEXPORT long LIBCALL getClockFrequency(HANDLE devpointer);
LIBEXPORT bool LIBCALL getSlowIOlimits(unsigned long* numouts, unsigned long* numins, HANDLE devpointer);
LIBEXPORT bool LIBCALL getBoardStatus(BYTE* bstat, HANDLE devpointer);
LIBEXPORT BYTE LIBCALL castIntToByte(long in);
LIBEXPORT long LIBCALL castByteToInt(BYTE in);
LIBEXPORT bool LIBCALL allocateNewProtocol(long pindex, long numloops, long numbitmasks, HANDLE devpointer);
LIBEXPORT bool LIBCALL repeatLoop(long pindex, long lindex, long numreps,HANDLE devpointer);
LIBEXPORT bool LIBCALL addBitmask(long pindex, long lindex, unsigned long bitmask, unsigned long cycles,HANDLE devpointer);
LIBEXPORT bool LIBCALL setTerminalBitmask(long pindex, unsigned long bitmask,HANDLE devpointer);
LIBEXPORT bool LIBCALL freeMemory(long pindex, HANDLE devpointer);
LIBEXPORT bool LIBCALL runProtocol(long pindex, HANDLE devpointer); // doesn't return until finished
LIBEXPORT bool LIBCALL startProtocol(long pindex, HANDLE devpointer); // returns immediately, need to you checkIfDone() to determine when protocol is done
LIBEXPORT bool LIBCALL checkIfDone(HANDLE devpointer);
LIBEXPORT bool LIBCALL killProtocol(HANDLE devpointer);
LIBEXPORT bool LIBCALL changeOutputBitmask(unsigned long bitmask,HANDLE devpointer);
LIBEXPORT bool LIBCALL slowIOreadByte(BYTE address, BYTE* getbyte, HANDLE devpointer);
LIBEXPORT bool LIBCALL slowIOwriteByte(BYTE address,BYTE setbyte, HANDLE devpointer);
LIBEXPORT bool LIBCALL refreshBoard(HANDLE devpointer);
LIBEXPORT bool LIBCALL sendCommand(BYTE command,HANDLE devpointer);
LIBEXPORT bool LIBCALL sendCommandWithParameters(BYTE command,long p1, long p2, long p3, long p4, HANDLE devpointer);
LIBEXPORT bool LIBCALL writeInt32(unsigned long number, BYTE startindex, HANDLE devpointer);
LIBEXPORT bool LIBCALL readInt32(unsigned long* number, BYTE startindex, HANDLE devpointer);
#ifdef __cplusplus
}
#endif
// Global Variables
string error_message = "No errors yet.";
HANDLE device_table[256]; // for JNI functions
const long device_limit = 256; // for JNI functions
/*
* bool initDrivers()
* <p>
* returns true if successful, false otherwise
* <p>
* Must be called before anything else will work
* */
LIBEXPORT bool LIBCALL initDrivers(){
for(int i = 0; i < 256; i++){
device_table[i] = NULL;
}
ERC code = 0;
bool success = true;
success = success && DpcInit(&code);
error_message = errorCodeToMessage(code);
return success;
}
/**
* bool openChrisBlasterConnection(char* name, HANDLE* devpointer)
* <p>
* returns true if connection was successful, false otherwise
* <p>
* Before using any data transfer functions, the application must connect to a
* communication device using DpcOpenData. The first parameter is a pointer to
* an interface handle (hif). If the function returns successfully, this handle
* will be used to connect to the device in all proceeding data transfer calls.
* The device is specified by its assigned name in the device table and passed
* as the second parameter in the DpcOpenData function.
* */
LIBEXPORT bool LIBCALL openChrisBlasterConnection(char* name, HANDLE* devpointer){
ERC code = 0;
bool success = true;
success = success && DpcOpenData(devpointer, name, &code, NULL);
error_message = errorCodeToMessage(code);
return success;
}
/**
* bool closeChrisBlasterConnection(HANDLE devpointer)
* <p>
* returns true if connection was successfully closed, false otherwise
* */
LIBEXPORT bool LIBCALL closeChrisBlasterConnection(HANDLE devpointer){
ERC code = 0;
bool success = true;
success = success && DpcCloseData(devpointer,&code);
error_message = errorCodeToMessage(code);
return success;
}
/**
* long getClockFrequency(HANDLE devpointer)
* <p>
* returns the FPGA clock frequency in Hz. This should be used to calibrate
* the conversion of times into clock cycles. Returns 0 if the connection fails.
* */
LIBEXPORT long LIBCALL getClockFrequency(HANDLE devpointer){
bool success = true;
unsigned long freq = 0;
success = success && sendCommand((BYTE) GET_CLOCK, devpointer);
success = success && readInt32(&freq,(BYTE) REGISTER_DATA,devpointer);
if(success){
return freq;
} else {
return 0;
}
}
/**
* bool getSlowIOlimits(long* numouts, long* numins, HANDLE devpointer)
* <p>
* stores the number of slow output bytes in numouts and the number of input
* bytes in numins. Returns true if the connection was successful and false
* otherwise.
* */
LIBEXPORT bool LIBCALL getSlowIOlimits(unsigned long* numouts, unsigned long* numins, HANDLE devpointer){
bool success = TRUE;
success = success && sendCommand((BYTE) SLOW_IO_GET_READ_SIZE, devpointer);
success = success && readInt32(numins,(BYTE) REGISTER_DATA,devpointer);
success = success && sendCommand((BYTE) SLOW_IO_GET_WRITE_SIZE, devpointer);
success = success && readInt32(numouts,(BYTE) REGISTER_DATA,devpointer);
return success;
}
/**
* bool getBoardStatus(BYTE* bstat, HANDLE devpointer)
* <p>
* gets the current status of the board and stores it in bstat.
* <p>
* returns true if the connection was successful
* */
LIBEXPORT bool LIBCALL getBoardStatus(BYTE* bstat, HANDLE devpointer){
ERC code = 0;
bool success = TRUE;
success = success && DpcGetReg(devpointer, (BYTE) REGISTER_STATUS, bstat, &code, NULL);
error_message = errorCodeToMessage(code);
return success;
}
/**
* BYTE castIntToByte(long in)
* <p>
* returns the BYTE conversion of in [0 , 256)
* */
LIBEXPORT BYTE LIBCALL castIntToByte(long in){
return (BYTE) (in % 256);
}
/**
* long castByteToInt(BYTE in)
* <p>
* returns the 32-bit integer conversion of in
* */
LIBEXPORT long LIBCALL castByteToInt(BYTE in){
return (long) in;
}
/**
* bool allocateNewProtocol(long pindex, long numloops, long numbitmasks, HANDLE devpointer)
* <p>
* Tells the ChrisBlaster board to allocate memory for a protocol at index
* numner pindex.
* <p>
* returns true on successful execution, false otherwise
* */
LIBEXPORT bool LIBCALL allocateNewProtocol(long pindex, long numloops, long numbitmasks, HANDLE devpointer){
return sendCommandWithParameters((BYTE) NEW_PROTOCOL,
pindex, numloops, numbitmasks, 0, devpointer);
}
/**
* bool LIBCALL (long pindex, long lindex, long numreps,HANDLE devpointer)
* <p>
* Tells the ChrisBlaster board to how many times to loop through the bitmasks
* of protocol number pindex, loop number lindex
* <p>
* returns true on successful execution, false otherwise
* */
LIBEXPORT bool LIBCALL repeatLoop(long pindex, long lindex, long numreps,HANDLE devpointer){
return sendCommandWithParameters((BYTE) SET_LOOP_REP,
pindex, lindex, numreps, 0, devpointer);
}
/**
* bool addBitmask(long pindex, long lindex, unsigned long bitmask, unsigned long cycles,HANDLE devpointer);
* <p>
* adds the specified bitmask to protocol number pindex, loop number lindex, and
* sets that bitmask to persist for cycles clock cycles.
* <p>
* returns true on successful execution, false otherwise
* */
LIBEXPORT bool LIBCALL addBitmask(long pindex, long lindex, unsigned long bitmask, unsigned long cycles,HANDLE devpointer){
return sendCommandWithParameters((BYTE) ADD_BITMASK,
pindex, lindex, bitmask, cycles, devpointer);
}
/**
* bool setTerminalBitmask(long pindex, unsigned long bitmask,HANDLE devpointer)
* <p>
* Sets the bitmask that protocol number pindex should revert to after it
* completes its execution
* <p>
* returns true on successful execution, false otherwise
* */
LIBEXPORT bool LIBCALL setTerminalBitmask(long pindex, unsigned long bitmask,HANDLE devpointer){
return sendCommandWithParameters((BYTE) SET_TERMINAL_BITMASK,
pindex, bitmask, 0, 0, devpointer);
}
/**
* bool freeMemory(long pindex, HANDLE devpointer)
* <p>
* frees protocol number pindex from the board's memory and erases its program
* <p>
* returns true on successful execution, false otherwise
* */
LIBEXPORT bool LIBCALL freeMemory(long pindex, HANDLE devpointer){
return sendCommandWithParameters((BYTE) ERASE_PROTOCOL,
pindex, 0, 0, 0, devpointer);
}
/**
* bool runProtocol(long pindex, HANDLE devpointer)
* <p>
* Starts the indicated protocol and then does not return until that protocol is
* finished or an error occures.
* <p>
* returns true after successful execution, false if an error occures
* */
LIBEXPORT bool LIBCALL runProtocol(long pindex, HANDLE devpointer){
ERC code = 0;
bool success = TRUE;
success = success && sendCommandWithParameters((BYTE) RUN_PROTOCOL,
pindex, 0, 0, 0, devpointer);
BYTE boardstat;
do{
CROSSPLATSLEEP(100);
success = success && DpcGetReg(devpointer, (BYTE) REGISTER_STATUS, &boardstat, &code, NULL);
} while(success && boardstat == STATUS_RUNNING);
error_message = errorCodeToMessage(code);
if(boardstat == STATUS_ERROR){
return FALSE;
}
return success;
}
/**
* bool startProtocol(long pindex, HANDLE devpointer)
* <p>
* Starts the indicated protocol and then returns. You should use checkIfDone()
* to periodically poll the ChrisBlaster to know when the protocol is finished
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL startProtocol(long pindex, HANDLE devpointer){
return sendCommandWithParameters((BYTE) RUN_PROTOCOL,
pindex, 0, 0, 0, devpointer);
}
/**
* bool checkIfDone(HANDLE devpointer)
* <p>
* returns true if the last protocol has finished, false if it is still running
* */
LIBEXPORT bool LIBCALL checkIfDone(HANDLE devpointer){
BYTE status = 0;
getBoardStatus(&status, devpointer);
if(status == STATUS_RUNNING) {
return FALSE;
} else {
return TRUE;
}
}
/**
* bool killProtocol(HANDLE devpointer)
* <p>
* Kills the currently running protocol and sets the bitmask to zeroes
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL killProtocol(HANDLE devpointer){
return sendCommand(ABORT,devpointer);
}
/**
* bool changeOutputBitmask(unsigned long bitmask,HANDLE devpointer)
* <p>
* changes the current non-protocol bitmask. This is primarily used for
* controlling the actinic lights
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL changeOutputBitmask(unsigned long bitmask,HANDLE devpointer){
return sendCommandWithParameters((BYTE) SET_CURRENT_BITMASK,
bitmask, 0, 0, 0, devpointer);
}
/**
* bool slowIOreadByte(BYTE address, BYTE* getbyte, HANDLE devpointer)
* <p>
* reads the slow input byte whose index is address into getbyte
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL slowIOreadByte(BYTE address, BYTE* getbyte, HANDLE devpointer){
bool success = TRUE;
success = success && sendCommandWithParameters((BYTE) SLOW_IO_READ_BYTE,
address, 0, 0, 0, devpointer);
unsigned long slowbyte;
success = success && readInt32(&slowbyte, (BYTE) REGISTER_DATA, devpointer);
*getbyte = (BYTE) (slowbyte % 256);
return success;
}
/**
* bool slowIOwriteByte(BYTE address,BYTE setbyte, HANDLE devpointer)
* <p>
* writes to the slow output byte whose index is address
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL slowIOwriteByte(BYTE address,BYTE setbyte, HANDLE devpointer){
return sendCommandWithParameters((BYTE) SLOW_IO_WRITE_BYTE,
address, setbyte, 0, 0, devpointer);
}
/**
* bool refreshBoard(HANDLE devpointer)
* <p>
* resets the board status, so if it was previously in an error state, it is now
* back to the ready state
* <p>
* returns true if the command was sent successfully, false if an error occures
* */
LIBEXPORT bool LIBCALL refreshBoard(HANDLE devpointer){
return sendCommand(RESET_STATUS,devpointer);
}
LIBEXPORT bool LIBCALL sendCommand(BYTE command,HANDLE devpointer){
ERC code;
bool success = TRUE;
success = success && DpcPutReg(devpointer, (BYTE) REGISTER_COMMAND, command, &code, NULL);
success = success && DpcPutReg(devpointer, (BYTE) REGISTER_SWAP, SWAP_ACTIVE, &code, NULL);
if(!success){ // errors occured
error_message = errorCodeToMessage(code);
return success;
}
BYTE swapvalue;
do{
success = success && DpcGetReg(devpointer, (BYTE) REGISTER_SWAP, &swapvalue, &code, NULL);
} while(success && swapvalue == SWAP_ACTIVE);
return success;
}
LIBEXPORT bool LIBCALL sendCommandWithParameters(BYTE command,long p1, long p2, long p3, long p4, HANDLE devpointer){
ERC code;
bool success = TRUE;
// first, set the parameters
success = success && writeInt32(p1, (BYTE) REGISTER_PARAM1, devpointer);
success = success && writeInt32(p2, (BYTE) REGISTER_PARAM2, devpointer);
success = success && writeInt32(p3, (BYTE) REGISTER_PARAM3, devpointer);
success = success && writeInt32(p4, (BYTE) REGISTER_PARAM4, devpointer);
// then send the command code and then set the swap to active
success = success && DpcPutReg(devpointer, (BYTE) REGISTER_COMMAND, command, &code, NULL);
success = success && DpcPutReg(devpointer, (BYTE) REGISTER_SWAP, SWAP_ACTIVE, &code, NULL);
if(!success){ // errors occured
error_message = errorCodeToMessage(code);
return success;
}
BYTE swapvalue;
do{
success = success && DpcGetReg(devpointer, (BYTE) REGISTER_SWAP, &swapvalue, &code, NULL);
} while(success && swapvalue == SWAP_ACTIVE);
return success;
}
LIBEXPORT bool LIBCALL writeInt32(unsigned long number, BYTE startindex, HANDLE devpointer){
ERC code;
bool success = TRUE;
success = success && DpcPutReg(devpointer, (BYTE) startindex, (BYTE) Int32ToByte0(number), &code, NULL);
success = success && DpcPutReg(devpointer, (BYTE) (startindex + 1), (BYTE) Int32ToByte1(number), &code, NULL);
success = success && DpcPutReg(devpointer, (BYTE) (startindex + 2), (BYTE) Int32ToByte2(number), &code, NULL);
success = success && DpcPutReg(devpointer, (BYTE) (startindex + 3), (BYTE) Int32ToByte3(number), &code, NULL);
if(!success) error_message = errorCodeToMessage(code);
return success;
}
LIBEXPORT bool LIBCALL readInt32(unsigned long* number, BYTE startindex, HANDLE devpointer){
ERC code;
bool success = TRUE;
BYTE bb[4];
success = success && DpcGetReg(devpointer, (BYTE) startindex, &bb[0], &code, NULL);
success = success && DpcGetReg(devpointer, (BYTE) (startindex + 1), &bb[1], &code, NULL);
success = success && DpcGetReg(devpointer, (BYTE) (startindex + 2), &bb[2], &code, NULL);
success = success && DpcGetReg(devpointer, (BYTE) (startindex + 3), &bb[3], &code, NULL);
if(!success){ // errors occured
error_message = errorCodeToMessage(code);
return success;
}
*number = BytesToInt32(bb[0],bb[1],bb[2],bb[3]);
return success;
}
/**
* LIBEXPORT void LIBCALL getErrorMessage(char* msgbuff, int length)
* <p>
* Puts the last error message in msgbuff
* */
LIBEXPORT void LIBCALL getErrorMessage(char* msgbuff, int length){
strncpy(msgbuff, error_message.c_str(), length);
}
/**
* conversts the error code into a short message based on dpcdefs.h
* */
LIBEXPORT string LIBCALL errorCodeToMessage(int code){
string message;
switch (code){
case ercNoError:
message = "No error";
break;
case ercConnReject:
message = "ercConnReject";
break;
case ercConnType:
message = "ercConnType";
break;
case ercConnNoMode:
message = "ercConnNoMode";
break;
case ercInvParam:
message = "ercInvParam";
break;
case ercInvCmd:
message = "ercInvCmd";
break;
case ercUnknown:
message = "ercUnknown";
break;
case ercJtagConflict:
message = "ercJtagConflict";
break;
case ercNotImp:
message = "ercNotImp";
break;
case ercNoMem:
message = "ercNoMem";
break;
case ercTimeout:
message = "ercTimeout";
break;
case ercConflict:
message = "ercConflict";
break;
case ercBadPacket:
message = "ercBadPacket";
break;
case ercInvOption:
message = "ercInvOption";
break;
case ercAlreadyCon:
message = "ercAlreadyCon";
break;
case ercConnected:
message = "ercConnected";
break;
case ercNotInit:
message = "ercNotInit";
break;
case ercCantConnect:
message = "ercCantConnect";
break;
case ercAlreadyConnect:
message = "ercAlreadyConnect";
break;
case ercSendError:
message = "ercSendError";
break;
case ercRcvError:
message = "ercRcvError";
break;
case ercAbort:
message = "ercAbort";
break;
case ercTimeOut:
message = "ercTimeOut";
break;
case ercOutOfOrder:
message = "ercOutOfOrder";
break;
case ercExtraData:
message = "ercExtraData";
break;
case ercMissingData:
message = "ercMissingData";
break;
case ercTridNotFound:
message = "ercTridNotFound";
break;
case ercNotComplete:
message = "ercNotComplete";
break;
case ercNotConnected:
message = "ercNotConnected";
break;
case ercWrongMode:
message = "ercWrongMode";
break;
case ercWrongVersion:
message = "ercWrongVersion";
break;
case ercDvctableDne:
message = "ercDvctableDne";
break;
case ercDvctableCorrupt:
message = "ercDvctableCorrupt";
break;
case ercDvcDne:
message = "ercDvcDne";
break;
case ercDpcutilInitFail:
message = "ercDpcutilInitFail";
break;
case ercUnknownErr:
message = "ercUnknownErr";
break;
case ercDvcTableOpen:
message = "ercDvcTableOpen";
break;
case ercRegError:
message = "ercRegError";
break;
case ercNotifyRegFull:
message = "ercNotifyRegFull";
break;
case ercNotifyNotFound:
message = "ercNotifyNotFound";
break;
case ercOldDriverNewFw:
message = "ercOldDriverNewFw";
break;
case ercInvHandle:
message = "ercInvHandle";
break;
default:
message = "Could not identify error code";
break;
}
return message;
}
////////// JAVA-NATIVE INTERFACE FUNCTIONS //////////
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: initializeDrivers
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_initializeDrivers
(JNIEnv *env, jclass callingclass){
jboolean success = initDrivers();
return success;
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: open
* Signature: (Ljava/lang/String;)Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_connect
(JNIEnv *env, jclass callingclass, jstring jname, jobject device) {
jboolean boo;
jboolean success = JNI_TRUE;
const char* cname = env->GetStringUTFChars(jname, &boo);
int len = 512;
char boardname[512];
strncpy(boardname, cname, len);
// find lowest NULL handle
jint devindex = -1;
for (int i = 0; i < device_limit; i++) {
if (devindex < 0 && device_table[i] == NULL) {
devindex = i;
break;
}
}
if (openChrisBlasterConnection(boardname, &device_table[devindex])) {
// successful connection
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class, "device_table_index", "I");
env->SetIntField(device, device_table_index_id, devindex);
jint clockspeed = getClockFrequency(device_table[devindex]);
jfieldID clock_id = env->GetFieldID(device_class, "clock_frequency", "I");
env->SetIntField(device, clock_id, clockspeed);
BYTE status_byte = 0;
getBoardStatus(&status_byte, device_table[devindex]);
jint status = status_byte;
jfieldID status_id = env->GetFieldID(device_class, "status", "I");
env->SetIntField(device, status_id, status);
jfieldID name_id = env->GetFieldID(device_class, "name", "Ljava/lang/String;");
env->SetObjectField(device, name_id, jname);
} else {
// unsuccessful connection (e.g. wrong name)
success = JNI_FALSE;
}
env->ReleaseStringUTFChars(jname, cname);
return success;
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: close
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_close
(JNIEnv *env, jclass callingclass, jobject device){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(closeChrisBlasterConnection(device_table[devindex])){
device_table[devindex] = NULL;
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: getChrisBlasterStatus
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_getChrisBlasterStatus
(JNIEnv *env, jclass callingclass, jobject device){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
BYTE status_byte = 0;
bool success = getBoardStatus(&status_byte, device_table[devindex]);
jint status = status_byte;
jfieldID status_id = env->GetFieldID(device_class, "status", "I");
env->SetIntField(device, status_id, status);
if (success) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: getLastErrorMessage
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jstring JNICALL Java_chrisblaster_ChrisBlasterManager_getLastErrorMessage
(JNIEnv *env, jclass callingclass){
return env->NewStringUTF(error_message.c_str());
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: allocateProtocol
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;III)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_allocateProtocol
(JNIEnv *env, jclass callingclass, jobject device, jint index, jint nloops, jint nmasks){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(allocateNewProtocol(index,nloops,nmasks,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: setLoopRepeat
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;III)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_setLoopRepeat
(JNIEnv *env, jclass callingclass, jobject device, jint pindex, jint lindex, jint reps){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(repeatLoop(pindex,lindex,reps,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: addBitmask
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;IIII)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_addBitmask
(JNIEnv *env, jclass callingclass, jobject device, jint pindex, jint lindex, jint mask, jint cycles){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(addBitmask(pindex,lindex,mask,cycles,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: setTerminalBitmask
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;II)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_setTerminalBitmask
(JNIEnv *env, jclass callingclass, jobject device, jint pindex, jint mask){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(setTerminalBitmask(pindex,mask,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: deallocateProtocol
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;I)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_deallocateProtocol
(JNIEnv *env, jclass callingclass, jobject device, jint pindex){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(freeMemory(pindex,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: startProtocol
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;I)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_startProtocol
(JNIEnv *env, jclass callingclass, jobject device, jint pindex){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(startProtocol(pindex,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: isRunningProtocol
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_isRunningProtocol
(JNIEnv *env, jclass callingclass, jobject device){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(checkIfDone(device_table[devindex])){
// done, return false
return JNI_FALSE;
}else{
// not done yet, return true
return JNI_TRUE;
}
// sorry the above code is confusing.
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: abortProtocol
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_abortProtocol
(JNIEnv *env, jclass callingclass, jobject device){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(killProtocol(device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: setCurrentBitmask
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;I)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_setCurrentBitmask
(JNIEnv *env, jclass callingclass, jobject device, jint mask){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(changeOutputBitmask(mask,device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
/*
* Class: chrisblaster_ChrisBlasterManager
* Method: refresh
* Signature: (Lchrisblaster/ChrisBlasterManager/ChrisBlasterDevice;)Z
*/
JNIEXPORT jboolean JNICALL Java_chrisblaster_ChrisBlasterManager_refresh
(JNIEnv *env, jclass callingclass, jobject device){
jclass device_class = env->GetObjectClass(device);
jfieldID device_table_index_id = env->GetFieldID(device_class,"device_table_index","I");
long devindex = env->GetIntField(device,device_table_index_id);
if(refreshBoard(device_table[devindex])){
return JNI_TRUE;
}else{
return JNI_FALSE;
}
}
////////// END OF JNI FUNCTIONS //////////