Skip to content

Commit a1d5c96

Browse files
committed
wip
Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
1 parent 7b4da47 commit a1d5c96

3 files changed

Lines changed: 113 additions & 90 deletions

File tree

src/board_controller/muse/inc/muse_anthena.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class MuseAnthena : public BLELibBoard
2323

2424
std::string bytes_to_string (const uint8_t *data, size_t size);
2525

26-
void parse_eeg_packet (const uint8_t *data, size_t size);
27-
void parse_ppg_packet (const uint8_t *data, size_t size);
26+
void parse_main_packet (const uint8_t *data, size_t start_pos, size_t size);
27+
void parse_sensor_packet (const uint8_t *data, size_t start_pos, size_t size);
2828

2929
public:
3030
MuseAnthena (int board_id, struct BrainFlowInputParams params);
@@ -38,7 +38,7 @@ class MuseAnthena : public BLELibBoard
3838
int config_board (std::string config);
3939

4040
void adapter_on_scan_found (simpleble_adapter_t adapter, simpleble_peripheral_t peripheral);
41-
void peripheral_on_eeg (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
41+
void peripheral_on_main (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
4242
simpleble_uuid_t characteristic, const uint8_t *data, size_t size);
4343
void peripheral_on_aux (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
4444
simpleble_uuid_t characteristic, const uint8_t *data, size_t size);

src/board_controller/muse/inc/muse_anthena_constants.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,21 @@
77
#define MUSE_ANTHENA_GATT_ATTR_STREAM_TOGGLE "273e0001-4c4d-454d-96be-f03bac821358"
88
#define MUSE_ANTHENA_GATT_EEG "273e0013-4c4d-454d-96be-f03bac821358"
99
#define MUSE_ANTHENA_GATT_AUX "273e0014-4c4d-454d-96be-f03bac821358"
10-
#define EEG_PACKET_TYPE 0X12
11-
#define PPG_PACKET_TYPE 0x11
1210

13-
// info for equations
14-
#define MUSE_ANTHENA_ACCELEROMETER_SCALE_FACTOR 0.0000610352
15-
#define MUSE_ANTHENA_GYRO_SCALE_FACTOR 0.007476
11+
// info about packet type
12+
#define MUSE_S_ANTHENA_EEG_FOUR_PACKET_TYPE 0x11
13+
#define MUSE_S_ANTHENA_EEG_EIGHT_PACKET_TYPE 0x12
14+
#define MUSE_S_ANTHENA_OPTICS_FOUR_PACKET_TYPE 0x34
15+
#define MUSE_S_ANTHENA_OPTICS_EIGHT_PACKET_TYPE 0x35
16+
#define MUSE_S_ANTHENA_OPTICS_SIXTEEN_PACKET_TYPE 0x36
17+
#define MUSE_S_ANTHENA_SENSOR_PACKET_TYPE 0x47
18+
#define MUSE_S_ANTHENA_STATUS_PACKET_TYPE 0x53
19+
#define MUSE_S_ANTHENA_BATTERY_PACKET_TYPE 0x98
20+
21+
#define MUSE_S_ANTHENA_EEG_FOUR_PACKET_SIZE 32
22+
#define MUSE_S_ANTHENA_EEG_EIGHT_PACKET_SIZE 32
23+
#define MUSE_S_ANTHENA_OPTICS_FOUR_PACKET_SIZE 34
24+
#define MUSE_S_ANTHENA_OPTICS_EIGHT_PACKET_SIZE 44
25+
#define MUSE_S_ANTHENA_OPTICS_SIXTEEN_PACKET_SIZE 44
26+
#define MUSE_S_ANTHENA_SENSOR_PACKET_SIZE 40
27+
#define MUSE_S_ANTHENA_STATUS_PACKET_SIZE 28

src/board_controller/muse/muse_anthena.cpp

Lines changed: 93 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ void anthena_adapter_on_scan_found (
1515
((MuseAnthena *)(board))->adapter_on_scan_found (adapter, peripheral);
1616
}
1717

18-
void anthena_peripheral_on_eeg (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
18+
void anthena_peripheral_on_main (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
1919
simpleble_uuid_t characteristic, const uint8_t *data, size_t size, void *board)
2020
{
21-
((MuseAnthena *)(board))->peripheral_on_eeg (peripheral, service, characteristic, data, size);
21+
((MuseAnthena *)(board))->peripheral_on_main (peripheral, service, characteristic, data, size);
2222
}
2323

2424
void anthena_peripheral_on_aux (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
@@ -166,7 +166,7 @@ int MuseAnthena::prepare_session ()
166166
if (strcmp (service.characteristics[j].uuid.value, MUSE_ANTHENA_GATT_EEG) == 0)
167167
{
168168
if (simpleble_peripheral_notify (muse_peripheral, service.uuid,
169-
service.characteristics[j].uuid, ::anthena_peripheral_on_eeg,
169+
service.characteristics[j].uuid, ::anthena_peripheral_on_main,
170170
(void *)this) == SIMPLEBLE_SUCCESS)
171171
{
172172
notified_characteristics.push_back (
@@ -213,7 +213,7 @@ int MuseAnthena::prepare_session ()
213213
{
214214
// enable everything by default
215215
// p21(eeg only) and p1034(sleep mode) and p1035 are also available
216-
res = config_board ("p21");
216+
res = config_board ("p1035");
217217
}
218218
else
219219
{
@@ -397,7 +397,7 @@ void MuseAnthena::adapter_on_scan_found (
397397
}
398398
}
399399

400-
void MuseAnthena::peripheral_on_eeg (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
400+
void MuseAnthena::peripheral_on_main (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
401401
simpleble_uuid_t characteristic, const uint8_t *data, size_t size)
402402
{
403403
safe_logger (spdlog::level::trace, "incoming packet: {}", bytes_to_string (data, size));
@@ -406,88 +406,83 @@ void MuseAnthena::peripheral_on_eeg (simpleble_peripheral_t peripheral, simplebl
406406
safe_logger (spdlog::level::trace, "unexpected size: {}", size);
407407
return;
408408
}
409-
// it ignores the 1st ble package since it has smth in the beginning and blocks with 0x11 +
410-
// packet sub number later
411-
// TODO: find out what is there in the beginning
412-
if ((data[9] == 0x11) || (data[9] == 0x12))
413-
{
414-
parse_eeg_packet (data, size);
415-
}
416-
else
417-
{
418-
safe_logger (spdlog::level::trace, "unsupported packet type: {}", data[9]);
419-
}
420-
}
421-
422-
void MuseAnthena::parse_eeg_packet (const uint8_t *data, size_t size)
423-
{
424-
int sub_number = (int)data[10];
425-
int last_index = 0;
426-
int num_rows = board_descr["default"]["num_rows"];
427-
double *package = new double[num_rows];
428-
std::vector<int> eeg_channels = board_descr["default"]["eeg_channels"];
429-
for (int i = 0; i < num_rows; i++)
430-
{
431-
package[i] = 0.0;
432-
}
433-
package[board_descr["default"]["package_num_channel"].get<int> ()] = (double)data[1];
434-
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
435409

436-
for (int i = 9; i < (int)size - 8; i++)
410+
for (size_t i = 9; i < size - 1;)
437411
{
438-
if ((data[i] == EEG_PACKET_TYPE) && (data[i + 1] == sub_number) && (last_index <= i - 9))
412+
switch (static_cast<int> (data[i]))
439413
{
440-
double gain = 1.0; // random value, I am not sure in equations at all
441-
double eeg_scale = (double)(4.5 / float ((pow (2, 16) - 1)) / gain * 1000000.);
442-
int eeg1_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 2);
443-
int eeg2_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 4);
444-
int eeg3_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 6);
445-
int eeg4_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 8);
446-
sub_number++;
447-
last_index = i;
448-
package[eeg_channels[0]] = eeg1_value;
449-
package[eeg_channels[1]] = eeg2_value;
450-
package[eeg_channels[2]] = eeg3_value;
451-
package[eeg_channels[3]] = eeg4_value;
452-
}
453-
}
454-
455-
push_package (package, (int)BrainFlowPresets::DEFAULT_PRESET);
456-
457-
delete[] package;
458-
}
459-
460-
void MuseAnthena::parse_ppg_packet (const uint8_t *data, size_t size)
461-
{
462-
int sub_number = (int)data[10];
463-
int last_index = 0;
464-
int num_rows = board_descr["auxiliary"]["num_rows"];
465-
double *package = new double[num_rows];
466-
std::vector<int> ppg_channels = board_descr["default"]["ppg_channels"];
467-
for (int i = 0; i < num_rows; i++)
468-
{
469-
package[i] = 0.0;
470-
}
471-
package[board_descr["default"]["package_num_channel"].get<int> ()] = (double)data[1];
472-
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
473-
474-
for (int i = 9; i < (int)size - 8; i++)
475-
{
476-
if ((data[i] == PPG_PACKET_TYPE) && (data[i + 1] == sub_number) && (last_index <= i - 9))
477-
{
478-
sub_number++;
479-
last_index = i;
480-
package[ppg_channels[0]] = (double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i]);
481-
package[ppg_channels[1]] =
482-
(double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i + 3]);
483-
package[ppg_channels[2]] =
484-
(double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i + 6]);
414+
case 0x11:
415+
if (((data[i + 1] == (last_sensor_packet_id + 1)) || (data[i + 1] == 0)) &&
416+
(i + MUSE_S_ANTHENA_MAIN_PACKET_SIZE <= size))
417+
{
418+
parse_main_packet (data, i, size);
419+
last_sensor_packet_id = data[i + 1];
420+
i += (MUSE_S_ANTHENA_MAIN_PACKET_SIZE + 1);
421+
}
422+
else
423+
{
424+
// safe_logger (spdlog::level::debug,
425+
// "new id: {} doesnt match old one: {} for sensor packet: {}", data[i + 1],
426+
// last_sensor_packet_id, bytes_to_string (data, size));
427+
i++;
428+
}
429+
break;
430+
case 0x47:
431+
if (((data[i + 1] == (last_sensor_packet_id + 1)) || (data[i + 1] == 0)) &&
432+
(i + MUSE_S_ANTHENA_SENSOR_PACKET_SIZE <= size))
433+
{
434+
parse_sensor_packet (data, i, size);
435+
last_sensor_packet_id = data[i + 1];
436+
i += (MUSE_S_ANTHENA_SENSOR_PACKET_SIZE + 1);
437+
}
438+
else
439+
{
440+
// safe_logger (spdlog::level::debug,
441+
// "new id: {} doesnt match old one: {} for sensor packet: {}", data[i + 1],
442+
// last_sensor_packet_id, bytes_to_string (data, size));
443+
i++;
444+
}
445+
break;
446+
case 0x53:
447+
if (((data[i + 1] == (last_status_packet_id + 1)) || (data[i + 1] == 0)) &&
448+
(i + MUSE_S_ANTHENA_STATUS_PACKET_SIZE <= size))
449+
{
450+
last_status_packet_id = data[i + 1];
451+
i += (MUSE_S_ANTHENA_STATUS_PACKET_SIZE + 1);
452+
}
453+
else
454+
{
455+
// safe_logger (spdlog::level::debug,
456+
// "new id: {} doesnt match old one: {} for status packet: {}", data[i + 1],
457+
// last_status_packet_id, bytes_to_string (data, size));
458+
i++;
459+
}
460+
break;
461+
case 0x12:
462+
if (((data[i + 1] == (last_traditional_packet_id + 1)) || (data[i + 1] == 0)) &&
463+
(i + MUSE_S_ANTHENA_TRADITIONAL_PACKET_SIZE <= size))
464+
{
465+
last_traditional_packet_id = data[i + 1];
466+
i += (MUSE_S_ANTHENA_TRADITIONAL_PACKET_SIZE + 1);
467+
}
468+
else
469+
{
470+
// safe_logger (spdlog::level::debug,
471+
// "new id: {} doesnt match old one: {} for last_traditional_packet_id "
472+
// "packet: {}",
473+
// data[i + 1], last_traditional_packet_id, bytes_to_string (data, size));
474+
i++;
475+
}
476+
break;
477+
default:
478+
// safe_logger (
479+
// spdlog::level::debug, "incoming packet: {}", bytes_to_string (data, size));
480+
// safe_logger ("Unknown packet type:" data[i]);
481+
// increase just by one, alternative would be to drop the entire transaction
482+
i++;
483+
break;
485484
}
486485
}
487-
488-
push_package (package, (int)BrainFlowPresets::AUXILIARY_PRESET);
489-
490-
delete[] package;
491486
}
492487

493488
void MuseAnthena::peripheral_on_aux (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
@@ -497,6 +492,22 @@ void MuseAnthena::peripheral_on_aux (simpleble_peripheral_t peripheral, simplebl
497492
safe_logger (spdlog::level::trace, "AUX packet: {}", bytes_to_string (data, size));
498493
}
499494

495+
void MuseAnthena::parse_main_packet (const uint8_t *data, size_t start_pos, size_t size)
496+
{
497+
}
498+
499+
void MuseAnthena::parse_sensor_packet (const uint8_t *data, size_t start_pos, size_t size)
500+
{
501+
if ((data == NULL) || (start_pos + MUSE_S_ANTHENA_SENSOR_PACKET_SIZE > size) ||
502+
(data[start_pos] != MUSE_S_ANTHENA_SENSOR_PACKET_TYPE))
503+
{
504+
// safe_logger (spdlog::level::warn, "invalid packet in parse_sensor_packet: {}",
505+
// bytes_to_string (data, size));
506+
return;
507+
}
508+
int packet_num = (int)data[start_pos + 1];
509+
int packet_sub_type = (data[start_pos + 2] << 8) | data[start_pos + 3];
510+
}
500511

501512
std::string MuseAnthena::bytes_to_string (const uint8_t *data, size_t size)
502513
{

0 commit comments

Comments
 (0)