-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThnkrEegDecoder.h
278 lines (237 loc) · 7.45 KB
/
ThnkrEegDecoder.h
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
#ifndef EEG_TAGM_THNKR_DECODER_H_
#define EEG_TAGM_THNKR_DECODER_H_
#define CRTSCTS 020000000000
#define DEBUG 1
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#ifdef __cplusplus
extern "C" {
#endif
/* name of the USB Port to connect to */
#define PORT_NAME "/dev/ttyUSB0"
#define MAX_PAYLOAD_SIZE 170
#define MAX_QUEUE_SIZE 10
#define BAUD_RATE B115200
/* Parser types */
#define THNKR_TYPE_NULL 0x00
#define THNKR_TYPE_PACKETS 0x01 /* Stream bytes as ThinkGear Packets */
#define THNKR_TYPE_2BYTERAW 0x02 /* Stream bytes as 2-byte raw data */
/* Data CODE definitions */
#define THNKR_CODE_BATTERY 0x01
#define THNKR_CODE_POOR_QUALITY 0x02
#define THNKR_CODE_ATTENTION 0x04
#define THNKR_CODE_MEDITATION 0x05
#define THNKR_CODE_BLINK 0x16
#define THNKR_CODE_8BITRAW_SIGNAL 0x06
#define THNKR_CODE_RAW_MARKER 0x07
/* Byte codes */
#define THNKR_CODE_LOW_VALUE 0x40
#define THNKR_CODE_RAW_SIGNAL 0x80
#define THNKR_CODE_EEG_POWERS 0x81
#define THNKR_CODE_ASIC_EEG_POWER_INT 0x83
#define THNKR_CODE_CONNECT 0xC0
#define THNKR_CODE_DISCONNECT 0xC1
#define THNKR_CODE_AUTOCONNECT 0xC2
#define THNKR_CODE_CONNECTED 0xD0
#define THNKR_CODE_NOT_FOUND 0xD1
#define THNKR_CODE_DISCONNECTED 0xD2
#define THNKR_CODE_DENIED 0xD3
#define THNKR_CODE_STANDBY_SCAN 0xD4
/* Decoder states (Packet decoding) */
#define THNKR_STATE_NULL 0x00 /* NULL state */
#define THNKR_STATE_SYNC 0x01 /* Waiting for SYNC byte */
#define THNKR_STATE_SYNC_CHECK 0x02 /* Waiting for second SYNC byte */
#define THNKR_STATE_PAYLOAD_LENGTH 0x03 /* Waiting for payload[] length */
#define THNKR_STATE_PAYLOAD 0x04 /* Waiting for next payload[] byte */
#define THNKR_STATE_CHKSUM 0x05 /* Waiting for chksum byte */
/* Decoder states (2-byte raw decoding) */
#define THNKR_STATE_WAIT_HIGH 0x06 /* Waiting for high byte */
#define THNKR_STATE_WAIT_LOW 0x07 /* High r'cvd. Expecting low part */
/* Other constants */
#define THNKR_SYNC_BYTE 0xAA /* Syncronization byte */
#define THNKR_EXCODE_BYTE 0x55 /* EXtended CODE level byte */
#define THNKR_MODE_BYTE 0x0F /* attention enabled, meditation enabled, raw wave enabled, 57.6k baud rate */
void __attribute__ ((constructor)) libmain(void);
void __attribute__ ((destructor)) disconnectAndClose(void);
/**
* The structure to hold our data from the EEG
* delta, theta, low-alpha, high-alpha, low-beta, high-beta, low-gamma, and mid-gamma
*/
typedef struct EegData {
unsigned int attention;
unsigned int meditation;
unsigned int delta;
unsigned int theta;
unsigned int lAlpha;
unsigned int hAlpha;
unsigned int lBeta;
unsigned int hBeta;
unsigned int lGamma;
unsigned int mGamma;
} EegData;
/**
* The Node struct,
* contains item and the pointer that point to next node.
*/
typedef struct Node {
struct EegData item;
struct Node* next;
} Node;
/**
* The Queue struct, contains the pointers that
* point to first node and last node, the size of the Queue,
* and the function pointers.
*/
typedef struct Queue {
Node* head;
Node* tail;
void (*push) (struct Queue*, EegData); // add item to tail
// get item from head and remove it from queue
EegData (*pop) (struct Queue*);
// get item from head but keep it in queue
EegData (*peek) (struct Queue*);
// size of this queue
int size;
} Queue;
/**
* Push an item into queue, if this is the first item,
* both queue->head and queue->tail will point to it,
* otherwise the oldtail->next and tail will point to it.
*/
void push(Queue* queue, EegData item);
/**
* Return and remove the first item.
*/
EegData pop(Queue* queue);
/**
* Return but not remove the first item.
*/
EegData peek(Queue* queue);
/**
* Initializing the Queue
*/
Queue createQueue();
/**
* Global queue to hold our data
*/
Queue eegDataQueue;
/**
* The Parser is a state machine that manages the parsing state.
*/
typedef struct ThnkrEegDecoder {
unsigned char type;
unsigned char state;
unsigned char lastByte;
unsigned char payloadLength;
unsigned char payloadBytesReceived;
unsigned char payload[256];
unsigned char payloadSum;
unsigned char chksum;
void (*handleDataValue) (
unsigned char extendedCodeLevel,
unsigned char code,
unsigned char numBytes,
const unsigned char* value,
void* customData
);
void* customData;
} ThnkrEegDecoder;
/* GLOBAL our device TTY */
int dev = 0;
/**
* @param parser Pointer to a ThnkrEegDecoder object.
* @param parserType One of the THNKR_TYPE_* constants defined above:
* THNKR_TYPE_PACKETS or THNKR_TYPE_2BYTERAW.
* @param handleDataValueFunc A user-defined callback function that will
* be called whenever a data value is parsed
* from a Packet.
* @param customData A pointer to any arbitrary data that will
* also be passed to the handleDataValueFunc
* whenever a data value is parsed from a
* Packet.
*
* @return -1 if @c parser is NULL.
* @return -2 if @c parserType is invalid.
* @return 0 on success.
*/
int ThnkrEegDecoderInit(
ThnkrEegDecoder *pParser,
unsigned char parserType,
void (*handleDataValueFunc) (
unsigned char extendedCodeLevel,
unsigned char code,
unsigned char numBytes,
const unsigned char* value,
void* customData
),
void* customData
);
/**
* Feeds the @c byte into the @c parser. If the @c byte completes a
* complete, valid parser, then the @c parser's handleDataValue()
* function is automatically called on each DataRow in the Packet.
* The return value provides an indication of the state of the
* @c parser after parsing the byte.
*
* @param parser Pointer to an initialized ThinkGearDataParser object.
* @param byte The next byte of the data stream.
*
* @return -1 if @c parser is NULL.
* @return -2 if a complete Packet was received, but the checksum failed.
* @return -3 if an invalid Packet with PLENGTH > 170 was detected.
* @return -4 if an invalid Packet with PLENGTH == 170 was detected.
* @return -5 if the @c parser is somehow in an unrecognized state.
* @return 0 if the @c byte did not yet complete a Packet.
* @return 1 if a Packet was received and parsed successfully.
*
*/
int ThnkrEegDecoderParse(
ThnkrEegDecoder* pParser,
unsigned char byte
);
/**
* Function which acts on the value[] bytes of each ThinkGear DataRow as it is received.
*/
void handleDataValueFunc(
unsigned char extendedCodeLevel,
unsigned char code,
unsigned char valueLength,
const unsigned char *value,
void *customData
);
/**
* Sets the TTY (USB) interface attributes
*/
int setInterfaceAttributes(
int fd,
int speed,
int parity
);
/**
* This is the main entry point of the library
* and it will run the initialize function in a separate thread
*/
void libmain();
/**
* Initializez the ThnkGearEegConnector
*/
void* initialize(void* args);
/**
* isconnect and close PORT
*/
void disconnectAndClose();
/**
* EXPORTED function that gets data from the buffer
**/
extern char* getThnkrDataJSON();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* EEG_TAGM_THNKR_DECODER_H_ */