command.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "command.h"
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <inttypes.h>
  5. #include <stdio.h>
  6. #include <strings.h>
  7. #include <string.h>
  8. #include <sys/socket.h>
  9. #include <unistd.h>
  10. #include <time.h>
  11. #include "Devices/lmx2594.h"
  12. #include "Devices/dac8811.h"
  13. #include "Devices/ad9912.h"
  14. double f_pd = 200e6;
  15. //Массив структур Command, который связывает строки команд с соответствующими функциями.
  16. Command commands[] = {
  17. {"TMSG44:FREQ ", handleFreqCmd},
  18. {"TMSG44:LD?", handleLdCmd},
  19. {"TMSG44:POW ", handlePowCmd},
  20. {"TMSG44:ARM ", handleArmCmd},
  21. {"TMSG44:ATT ", handleAttCmd},
  22. {"*IDN?", handleIdnCmd},
  23. {NULL, NULL} // Завершающий элемент для обозначения конца массива
  24. };
  25. //handleXXXXCmd - обработчики команд
  26. void handleFreqCmd(const char* recvBuff)
  27. {
  28. printf("\nHandle command \"TMSG44:FREQ\"\n");
  29. double freq[1] = {0};
  30. double lmx_freq = 0;
  31. splitLexeme(recvBuff, freq, sizeof(freq[0]), convertToDouble);
  32. printf("Frequency: %.2f Hz\n", freq[0]);
  33. lmx_freq = lmx_get_freq(freq[0]);
  34. f_pd = ad9912_set(bar1, lmx_freq, f_pd);
  35. printf("f_pd frequency is set to %.6f MHz\n", f_pd/1e6);
  36. lmx_freq_set(bar1, lmx_freq, f_pd);
  37. // Switch the keys
  38. key_switch(bar1, freq[0],lmx_freq);
  39. printf("The frequency is set to %.2f MHz\n", freq[0]/1e6);
  40. }
  41. void handleLdCmd(const char* recvBuff)
  42. {
  43. int n = 0;
  44. char messageLd[] = "1\n";
  45. printf("\nHandle command \"TMSG44:LD?\"\n");
  46. uint32_t ld_status = lmx_ld_status(bar1);
  47. clock_t before = clock();
  48. clock_t difference;
  49. int difference_msec = 0;
  50. int trigger = 10000; //10ms
  51. while(!ld_status)
  52. {
  53. difference = clock() - before;
  54. difference_msec = difference * 1000 / CLOCKS_PER_SEC;
  55. if(difference_msec >= trigger)
  56. {
  57. strcpy(messageLd, "0\n");
  58. printf("LD timeout\n");
  59. break;
  60. }
  61. ld_status = lmx_ld_status(bar1);
  62. // printf("WHILE LD status: %d\n", ld_status);
  63. }
  64. send(conn_fd, messageLd, sizeof(messageLd), 0);
  65. printf("\nSend msg LD: %d!\n", ld_status);
  66. }
  67. void handlePowCmd(const char* recvBuff)
  68. {
  69. printf("\nHandle command \"TMSG44:POW\"\n");
  70. double pow[1] = {0};
  71. splitLexeme(recvBuff, pow, sizeof(pow[0]), convertToDouble);
  72. printf("%f\n", pow[0]);
  73. }
  74. void handleArmCmd(const char* recvBuff)
  75. {
  76. printf("\nHandle command \"TMSG44:ARM\"\n");
  77. uint16_t armCode[1] = {0};
  78. splitLexeme(recvBuff, armCode, sizeof(armCode[0]), convertToUInt16);
  79. printf("\n%u\n", armCode[0]);
  80. dac8811_set(bar1,armCode[0]);
  81. }
  82. void handleAttCmd(const char* recvBuff)
  83. {
  84. printf("\nHandle command \"TMSG44:ATT\"\n");
  85. uint16_t attCode[1] = {0};
  86. splitLexeme(recvBuff, attCode, sizeof(attCode[0]), convertToUInt16);
  87. printf("\n%u\n", attCode[0]);
  88. dac8811_att_set(bar1,attCode[0]);
  89. }
  90. void handleIdnCmd(const char* recvBuff)
  91. {
  92. printf("\nHandle command \"*IDN?\"\n");
  93. char messageIdn[] = "TMSG44_CoolPi\n";
  94. send(conn_fd, messageIdn, sizeof(messageIdn), 0);
  95. }
  96. //Проходим по массиву команд и ищем команду, которая совпадает с началом строки recvBuff.
  97. //Если команда найдена, вызывается соответствующая функция-обработчик
  98. void processCommand(const char* recvBuff)
  99. {
  100. for (int i = 0; commands[i].command != NULL; i++)
  101. {
  102. if (!strncasecmp(recvBuff, commands[i].command, strlen(commands[i].command)))
  103. {
  104. commands[i].handler(recvBuff);
  105. return;
  106. }
  107. }
  108. printf("\nUnknown command: %s\n", recvBuff);
  109. }
  110. // Преобразование строки в uint16_t
  111. void convertToUInt16(const char *str, void *output)
  112. {
  113. *(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
  114. }
  115. // Преобразование строки в unsigned long long int
  116. void convertToUint64(const char *str, void *output)
  117. {
  118. *(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
  119. }
  120. // Преобразование строки в double
  121. void convertToDouble(const char *str, void *output)
  122. {
  123. *(double *)output = strtod(str, NULL);
  124. }
  125. // Универсальная функция для разделения строки на лексемы
  126. void splitLexeme(const char *ptrSCPI, void *numOutAndValue, size_t elementSize, ConvertFunc convertFunc)
  127. {
  128. uint8_t counter = 0;
  129. // Разделители лексем
  130. const char charSeparator[] = {" "};
  131. char *ptrLexeme = NULL;
  132. // Указатель для хранения контекста токенизации
  133. char *savePtr;
  134. // Инициализируем функцию
  135. ptrLexeme = strtok_r((char *)ptrSCPI, charSeparator, &savePtr);
  136. // Ищем лексемы разделенные разделителем
  137. ptrLexeme = strtok_r(NULL, charSeparator, &savePtr);
  138. // Ищем лексемы строки
  139. while (ptrLexeme) {
  140. // Проверяем, является ли первый символ лексемы числом
  141. if(('0' <= ptrLexeme[0]) && (ptrLexeme[0] <= '9')) {
  142. // Преобразуем строку с числом в число
  143. convertFunc(ptrLexeme, (uint8_t *)numOutAndValue + counter * elementSize);
  144. counter++;
  145. }
  146. // Ищем лексемы разделенные разделителем
  147. ptrLexeme = strtok_r(NULL, charSeparator, &savePtr);
  148. }
  149. }