tcode.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "tcode.h"
  2. static TCodeCommandArray decode_device_command(const uint8_t* buffer, uint16_t size) {
  3. TCodeCommandArray command_array;
  4. if(size < 2) {
  5. command_array.size = 0;
  6. FURI_LOG_W("TCode Parser", "Unexpected code length for device command");
  7. return command_array;
  8. }
  9. command_array.size = 1;
  10. command_array.commands = malloc(sizeof(TCodeCommand));
  11. command_array.commands[0].command_type = Device;
  12. switch(buffer[1]) {
  13. case '0':
  14. FURI_LOG_T("TCode Parser", "Device Identification requested");
  15. command_array.commands[0].data.device_command = DeviceIdentification;
  16. break;
  17. case '1':
  18. FURI_LOG_T("TCode Parser", "TCode version requested");
  19. command_array.commands[0].data.device_command = TCodeVersion;
  20. break;
  21. case '2':
  22. FURI_LOG_T("TCode Parser", "Preferences list requested");
  23. command_array.commands[0].data.device_command = ListAxesAndUserRangePreferences;
  24. break;
  25. case 'S':
  26. FURI_LOG_T("TCode Parser", "Stop requested");
  27. command_array.commands[0].data.device_command = Stop;
  28. break;
  29. default:
  30. command_array.size = 0;
  31. break;
  32. }
  33. return command_array;
  34. }
  35. static TCodeCommandArray decode_general_command(const uint8_t* buffer, uint16_t size) {
  36. // size of the array = amount of spaces + 1
  37. uint16_t counter = 1;
  38. for(uint16_t i = 0; i < size; i++) {
  39. if(buffer[i] == 32) {
  40. counter++;
  41. }
  42. }
  43. FURI_LOG_T("TCode Parser", "Found %u commands in the message", counter);
  44. TCodeCommandArray commands_array;
  45. commands_array.size = counter;
  46. commands_array.commands = malloc(commands_array.size * sizeof(TCodeCommand));
  47. uint16_t position = 0;
  48. for(uint16_t i = 0; i < counter; i++) {
  49. TCodeCommand command;
  50. command.command_type = Unknown;
  51. TCodeCommandMotionType motion_type;
  52. switch(buffer[position]) {
  53. case 'L':
  54. case 'l':
  55. motion_type = Linear;
  56. break;
  57. case 'R':
  58. case 'r':
  59. motion_type = Rotate;
  60. break;
  61. case 'V':
  62. case 'v':
  63. motion_type = Vibrate;
  64. break;
  65. case 'A':
  66. case 'a':
  67. motion_type = Auxiliary;
  68. break;
  69. default: // error
  70. FURI_LOG_W("TCode Parser", "Unexpected motion type: %u", buffer[position]);
  71. return commands_array;
  72. }
  73. FURI_LOG_T("TCode Parser", "Parsed motion_type: %u", motion_type);
  74. position++;
  75. uint16_t channel = buffer[position] - 48; // single ascii character 0-9
  76. FURI_LOG_T("TCode Parser", "Parsed channel: %u", channel);
  77. position++;
  78. // X characters that are digits
  79. uint16_t current_position = position;
  80. while(buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
  81. position++;
  82. }
  83. uint8_t* magnitude = malloc(2 + (position - current_position) + 1); // "0.XXXX\0"
  84. magnitude[0] = '0';
  85. magnitude[1] = '.';
  86. for(uint16_t x = 0; x < (position - current_position); x++) {
  87. magnitude[x + 2] = buffer[current_position + x];
  88. }
  89. magnitude[position - current_position + 2] = '\0';
  90. float magnitude_float = strtof((char*)magnitude, NULL);
  91. free(magnitude);
  92. FURI_LOG_T("TCode Parser", "Parsed magnitude: %f", (double)magnitude_float);
  93. FURI_LOG_T("TCode Parser REMOVE ME", "Current position: %u, size: %u", position, size);
  94. FURI_LOG_T("TCode Parser REMOVE ME", "%u", buffer[position]);
  95. if(position == size || buffer[position] == ' ' || buffer[position] == '\n') {
  96. FURI_LOG_T("TCode Parser", "Command type: Magnitude");
  97. command.command_type = Magnitude;
  98. command.data.magnitude_command.motion_type = motion_type;
  99. command.data.magnitude_command.channel_id = channel;
  100. command.data.magnitude_command.magnitude = magnitude_float;
  101. commands_array.commands[i] = command;
  102. position++;
  103. continue;
  104. }
  105. uint8_t current_step = buffer[position];
  106. position++;
  107. uint16_t int_value = 0;
  108. while(buffer[position] >= 48 && buffer[position] <= 57 && position < size) {
  109. int_value *= 10;
  110. int_value += buffer[position] - 48;
  111. position++;
  112. }
  113. command.data.magnitude_time_interval_command.motion_type = motion_type;
  114. command.data.magnitude_time_interval_command.channel_id = channel;
  115. command.data.magnitude_time_interval_command.magnitude = magnitude_float;
  116. if(current_step == 'I' || current_step == 'i') {
  117. FURI_LOG_T("TCode Parser", "Command type: MagnitudeTimeInterval");
  118. command.command_type = MagnitudeTimeInterval;
  119. command.data.magnitude_time_interval_command.time_interval_milliseconds = int_value;
  120. }
  121. if(current_step == 'S' || current_step == 's') {
  122. FURI_LOG_T("TCode Parser", "Command type: MagnitudeSpeed");
  123. command.command_type = MagnitudeSpeed;
  124. command.data.magnitude_speed_command.speed_per_hundred_milliseconds = int_value;
  125. }
  126. if(command.command_type == Unknown) {
  127. FURI_LOG_W("TCode Parser", "Unknown command type!");
  128. }
  129. commands_array.commands[i] = command;
  130. position++;
  131. if(position >= size) {
  132. break;
  133. }
  134. }
  135. return commands_array;
  136. }
  137. TCodeCommandArray tcode_decode(uint8_t* buffer, uint16_t size) {
  138. switch(buffer[0]) {
  139. case 'd':
  140. case 'D':
  141. FURI_LOG_T("TCode Parser", "Parsing device command...");
  142. return decode_device_command(buffer, size);
  143. case 'l':
  144. case 'L':
  145. case 'r':
  146. case 'R':
  147. case 'v':
  148. case 'V':
  149. case 'a':
  150. case 'A':
  151. FURI_LOG_T("TCode Parser", "Parsing general command...");
  152. return decode_general_command(buffer, size);
  153. default: // error
  154. {
  155. TCodeCommandArray error;
  156. error.size = 0;
  157. error.commands = NULL;
  158. return error;
  159. }
  160. }
  161. }