mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2024-12-23 15:00:13 +00:00
183 lines
6.3 KiB
C
183 lines
6.3 KiB
C
|
#include "tcode.h"
|
||
|
|
||
|
static TCodeCommandArray decode_device_command(const uint8_t *buffer, uint16_t size) {
|
||
|
TCodeCommandArray command_array;
|
||
|
if (size < 2) {
|
||
|
command_array.size = 0;
|
||
|
FURI_LOG_W("TCode Parser", "Unexpected code length for device command");
|
||
|
return command_array;
|
||
|
}
|
||
|
|
||
|
command_array.size = 1;
|
||
|
command_array.commands = malloc(sizeof(TCodeCommand));
|
||
|
command_array.commands[0].command_type = Device;
|
||
|
|
||
|
switch (buffer[1]) {
|
||
|
case '0':
|
||
|
FURI_LOG_T("TCode Parser", "Device Identification requested");
|
||
|
command_array.commands[0].data.device_command = DeviceIdentification;
|
||
|
break;
|
||
|
case '1':
|
||
|
FURI_LOG_T("TCode Parser", "TCode version requested");
|
||
|
command_array.commands[0].data.device_command = TCodeVersion;
|
||
|
break;
|
||
|
case '2':
|
||
|
FURI_LOG_T("TCode Parser", "Preferences list requested");
|
||
|
command_array.commands[0].data.device_command = ListAxesAndUserRangePreferences;
|
||
|
break;
|
||
|
case 'S':
|
||
|
FURI_LOG_T("TCode Parser", "Stop requested");
|
||
|
command_array.commands[0].data.device_command = Stop;
|
||
|
break;
|
||
|
default:
|
||
|
command_array.size = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return command_array;
|
||
|
}
|
||
|
|
||
|
static TCodeCommandArray decode_general_command(const uint8_t *buffer, uint16_t size) {
|
||
|
// size of the array = amount of spaces + 1
|
||
|
uint16_t counter = 1;
|
||
|
for (uint16_t i = 0; i < size; i++) {
|
||
|
if (buffer[i] == 32) {
|
||
|
counter++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FURI_LOG_T("TCode Parser", "Found %u commands in the message", counter);
|
||
|
|
||
|
TCodeCommandArray commands_array;
|
||
|
commands_array.size = counter;
|
||
|
commands_array.commands = malloc(commands_array.size * sizeof(TCodeCommand));
|
||
|
|
||
|
uint16_t position = 0;
|
||
|
for (uint16_t i = 0; i < counter; i++) {
|
||
|
TCodeCommand command;
|
||
|
command.command_type = Unknown;
|
||
|
|
||
|
TCodeCommandMotionType motion_type;
|
||
|
switch (buffer[position]) {
|
||
|
case 'L':
|
||
|
case 'l':
|
||
|
motion_type = Linear;
|
||
|
break;
|
||
|
case 'R':
|
||
|
case 'r':
|
||
|
motion_type = Rotate;
|
||
|
break;
|
||
|
case 'V':
|
||
|
case 'v':
|
||
|
motion_type = Vibrate;
|
||
|
break;
|
||
|
case 'A':
|
||
|
case 'a':
|
||
|
motion_type = Auxiliary;
|
||
|
break;
|
||
|
default: // error
|
||
|
FURI_LOG_W("TCode Parser", "Unexpected motion type: %u", buffer[position]);
|
||
|
return commands_array;
|
||
|
}
|
||
|
FURI_LOG_T("TCode Parser", "Parsed motion_type: %u", motion_type);
|
||
|
position++;
|
||
|
|
||
|
uint16_t channel = buffer[position] - 48; // single ascii character 0-9
|
||
|
FURI_LOG_T("TCode Parser", "Parsed channel: %u", channel);
|
||
|
position++;
|
||
|
|
||
|
// X characters that are digits
|
||
|
uint16_t current_position = position;
|
||
|
while (buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
|
||
|
position++;
|
||
|
}
|
||
|
|
||
|
uint8_t *magnitude = malloc(2 + (position - current_position) + 1); // "0.XXXX\0"
|
||
|
magnitude[0] = '0';
|
||
|
magnitude[1] = '.';
|
||
|
for (uint16_t x = 0; x < (position - current_position); x++) {
|
||
|
magnitude[x + 2] = buffer[current_position + x];
|
||
|
}
|
||
|
magnitude[position - current_position + 2] = '\0';
|
||
|
float magnitude_float = strtof((char *) magnitude, NULL);
|
||
|
free(magnitude);
|
||
|
FURI_LOG_T("TCode Parser", "Parsed magnitude: %f", (double) magnitude_float);
|
||
|
|
||
|
FURI_LOG_T("TCode Parser REMOVE ME", "Current position: %u, size: %u", position, size);
|
||
|
FURI_LOG_T("TCode Parser REMOVE ME", "%u", buffer[position]);
|
||
|
if (position == size || buffer[position] == ' ' || buffer[position] == '\n') {
|
||
|
FURI_LOG_T("TCode Parser", "Command type: Magnitude");
|
||
|
command.command_type = Magnitude;
|
||
|
command.data.magnitude_command.motion_type = motion_type;
|
||
|
command.data.magnitude_command.channel_id = channel;
|
||
|
command.data.magnitude_command.magnitude = magnitude_float;
|
||
|
commands_array.commands[i] = command;
|
||
|
position++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
uint8_t current_step = buffer[position];
|
||
|
position++;
|
||
|
|
||
|
uint16_t int_value = 0;
|
||
|
while (buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
|
||
|
int_value *= 10;
|
||
|
int_value += buffer[position] - 48;
|
||
|
position++;
|
||
|
}
|
||
|
|
||
|
command.data.magnitude_time_interval_command.motion_type = motion_type;
|
||
|
command.data.magnitude_time_interval_command.channel_id = channel;
|
||
|
command.data.magnitude_time_interval_command.magnitude = magnitude_float;
|
||
|
|
||
|
if (current_step == 'I' || current_step == 'i') {
|
||
|
FURI_LOG_T("TCode Parser", "Command type: MagnitudeTimeInterval");
|
||
|
command.command_type = MagnitudeTimeInterval;
|
||
|
command.data.magnitude_time_interval_command.time_interval_milliseconds = int_value;
|
||
|
}
|
||
|
|
||
|
if (current_step == 'S' || current_step == 's') {
|
||
|
FURI_LOG_T("TCode Parser", "Command type: MagnitudeSpeed");
|
||
|
command.command_type = MagnitudeSpeed;
|
||
|
command.data.magnitude_speed_command.speed_per_hundred_milliseconds = int_value;
|
||
|
}
|
||
|
|
||
|
if (command.command_type == Unknown) {
|
||
|
FURI_LOG_W("TCode Parser", "Unknown command type!");
|
||
|
}
|
||
|
|
||
|
commands_array.commands[i] = command;
|
||
|
position++;
|
||
|
if (position >= size) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return commands_array;
|
||
|
}
|
||
|
|
||
|
TCodeCommandArray tcode_decode(uint8_t *buffer, uint16_t size) {
|
||
|
switch (buffer[0]) {
|
||
|
case 'd':
|
||
|
case 'D':
|
||
|
FURI_LOG_T("TCode Parser", "Parsing device command...");
|
||
|
return decode_device_command(buffer, size);
|
||
|
case 'l':
|
||
|
case 'L':
|
||
|
case 'r':
|
||
|
case 'R':
|
||
|
case 'v':
|
||
|
case 'V':
|
||
|
case 'a':
|
||
|
case 'A':
|
||
|
FURI_LOG_T("TCode Parser", "Parsing general command...");
|
||
|
return decode_general_command(buffer, size);
|
||
|
default: // error
|
||
|
{
|
||
|
TCodeCommandArray error;
|
||
|
error.size = 0;
|
||
|
error.commands = NULL;
|
||
|
return error;
|
||
|
}
|
||
|
}
|
||
|
}
|