command.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 <sys/time.h>
  10. #include <unistd.h>
  11. #include <time.h>
  12. #include "Devices/lmx2594.h"
  13. #include "Devices/dac8811.h"
  14. #include "Devices/ad9912.h"
  15. #include "Devices/potentiometer.h"
  16. double f_pd = 200e6;
  17. uint16_t armCode[1] = {0};
  18. uint16_t attCode[1] = {0};
  19. uint16_t offsetCode[1] = {0};
  20. uint16_t slopeCode[1] = {0};
  21. //Массив структур command, который связывает строки команд с соответствующими функциями.
  22. command commands[] = {
  23. {"TMSG44:FREQ ", handle_freq_cmd},
  24. {"TMSG44:LD?", handle_ld_cmd},
  25. {"TMSG44:POW ", handle_pow_cmd},
  26. {"TMSG44:ARM ", handle_arm_cmd},
  27. {"TMSG44:ATT ", handle_att_cmd},
  28. {"*IDN?", handle_idn_cmd},
  29. {"TMSG44:OFFSET ", handle_offset_cmd},
  30. {"TMSG44:SLOPE ", handle_slope_cmd},
  31. {NULL, NULL} // Завершающий элемент для обозначения конца массива
  32. };
  33. //handleXXXXCmd - обработчики команд
  34. void handle_freq_cmd(const char* recv_buff)
  35. {
  36. printf("\nHandle command \"TMSG44:FREQ\"\n");
  37. double freq[1] = {0};
  38. double lmx_freq = 0;
  39. split_lexeme(recv_buff, freq, sizeof(freq[0]), convert_to_double);
  40. lmx_freq = lmx_get_freq(freq[0]);
  41. f_pd = ad9912_set(pci_bar_1, lmx_freq, f_pd);
  42. printf("f_pd frequency is set to %.6f MHz\n", f_pd/1e6);
  43. lmx_freq_set(pci_bar_1, lmx_freq, f_pd);
  44. // Switch the keys
  45. key_switch(pci_bar_1, freq[0],lmx_freq);
  46. printf("The frequency is set to %.2f MHz\n", freq[0]/1e6);
  47. // Send the data
  48. send_data_qspi(pci_bar_1);
  49. // Return the 1 MOSI mode
  50. // usleep(1);
  51. // cfg_reg = get_cfg_reg();
  52. // SET_REGISTER_PARAM(cfg_reg,CFG_REG_SPI_MODE_BITM,CFG_REG_SPI_MODE_BITP, CFG_REG_SPI_MODE_1MOSI);
  53. // *spi_mode = cfg_reg;
  54. // set_cfg_reg(cfg_reg);
  55. }
  56. void send_data_qspi(reg_addr_pci* pci_bar_1) {
  57. // get the gpio reg and shift reg data
  58. uint32_t gpio_reg = get_tmsg_gpio_reg();
  59. uint32_t shift_reg = get_tmsg_shift_reg();
  60. // Create a header 4 Mosi mode
  61. uint32_t qspi_header = ((ENUM_SPIMODE_4MOSI) |
  62. (0x1 << BITP_GPIO_4MOSI_HEADER) |
  63. (0x1 << BITP_SHIFT_REG_4MOSI_HEADER ) |
  64. ((sizeof(ad9912_ftw_regs_qspi) / 4) << BITP_DDS_4MOSI_HEADER) |
  65. ((sizeof(lmx_change_freq_regs) / 4) << BITP_LMX2594_4MOSI_HEADER) |
  66. (TERM_BIT_1));
  67. pci_bar_1->sbtmsg_addr = qspi_header;
  68. // Initialize the registers
  69. // Send the data for AD9912
  70. for (int i = 0; i < sizeof(ad9912_ftw_regs_qspi) / 4; i++) {
  71. pci_bar_1->sbtmsg_addr = ad9912_ftw_regs_qspi[i];
  72. }
  73. // Send the data for the GPIO
  74. pci_bar_1->sbtmsg_addr = gpio_reg;
  75. // Send the data for LMX2594
  76. for (int i = 0; i < sizeof(lmx_change_freq_regs) / 4; i++) {
  77. pci_bar_1->sbtmsg_addr = lmx_change_freq_regs[i];
  78. }
  79. // Send the data for the shift register
  80. pci_bar_1->sbtmsg_addr = shift_reg;
  81. }
  82. void handle_ld_cmd(const char* recv_buff)
  83. {
  84. char messageLd[] = "1\n";
  85. printf("\nHandle command \"TMSG44:LD?\"\n");
  86. uint32_t ld_status = lmx_ld_status(pci_bar_1);
  87. clock_t before = clock();
  88. clock_t difference;
  89. int difference_msec = 0;
  90. int trigger = 10000; //10ms
  91. while(!ld_status)
  92. {
  93. difference = clock() - before;
  94. difference_msec = difference * 1000 / CLOCKS_PER_SEC;
  95. if(difference_msec >= trigger)
  96. {
  97. strcpy(messageLd, "0\n");
  98. printf("LD timeout\n");
  99. break;
  100. }
  101. ld_status = lmx_ld_status(pci_bar_1);
  102. // printf("WHILE LD status: %d\n", ld_status);
  103. }
  104. send(conn_fd, messageLd, sizeof(messageLd), 0);
  105. printf("\nSend msg LD: %d!\n", ld_status);
  106. }
  107. void handle_pow_cmd(const char* recv_buff)
  108. {
  109. printf("\nHandle command \"TMSG44:POW\"\n");
  110. double pow[1] = {0};
  111. split_lexeme(recv_buff, pow, sizeof(pow[0]), convert_to_double);
  112. printf("%f\n", pow[0]);
  113. }
  114. void handle_arm_cmd(const char* recv_buff)
  115. {
  116. printf("\nHandle command \"TMSG44:ARM\"\n");
  117. split_lexeme(recv_buff, armCode, sizeof(armCode[0]), convert_to_uint16);
  118. printf("\n%u\n", armCode[0]);
  119. dac8811_set_qspi(pci_bar_1, armCode[0]);
  120. }
  121. void handle_att_cmd(const char* recv_buff)
  122. {
  123. printf("\nHandle command \"TMSG44:ATT\"\n");
  124. split_lexeme(recv_buff, attCode, sizeof(attCode[0]), convert_to_uint16);
  125. printf("\n%u\n", attCode[0]);
  126. dac8811_att_set_qspi(pci_bar_1, attCode[0]);
  127. }
  128. void handle_idn_cmd(const char* recv_buff)
  129. {
  130. printf("\nHandle command \"*IDN?\"\n");
  131. char messageIdn[] = "TMSG44_CoolPi\n";
  132. send(conn_fd, messageIdn, sizeof(messageIdn), 0);
  133. }
  134. void handle_offset_cmd(const char* recv_buff)
  135. {
  136. printf("\nHandle command \"TMSG44:OFFSET\"\n");
  137. split_lexeme(recv_buff, offsetCode, sizeof(offsetCode[0]), convert_to_uint16);
  138. printf("\n%u\n", offsetCode[0]);
  139. potentiometer_set_offset(pci_bar_1, offsetCode[0]);
  140. }
  141. void handle_slope_cmd(const char* recv_buff)
  142. {
  143. printf("\nHandle command \"TMSG44:SLOPE\"\n");
  144. split_lexeme(recv_buff, slopeCode, sizeof(slopeCode[0]), convert_to_uint16);
  145. printf("\n%u\n", slopeCode[0]);
  146. potentiometer_set_slope(pci_bar_1, slopeCode[0]);
  147. }
  148. //Проходим по массиву команд и ищем команду, которая совпадает с началом строки recv_buff.
  149. //Если команда найдена, вызывается соответствующая функция-обработчик
  150. void process_command(const char* recv_buff)
  151. {
  152. for (int i = 0; commands[i].command != NULL; i++)
  153. {
  154. if (!strncasecmp(recv_buff, commands[i].command, strlen(commands[i].command)))
  155. {
  156. commands[i].handler(recv_buff);
  157. return;
  158. }
  159. }
  160. printf("\nUnknown command: %s\n", recv_buff);
  161. }
  162. // Преобразование строки в uint16_t
  163. void convert_to_uint16(const char *str, void *output)
  164. {
  165. *(uint16_t *)output = (uint16_t)strtoul(str, NULL, 10);
  166. }
  167. // Преобразование строки в unsigned long long int
  168. void convert_to_uint64(const char *str, void *output)
  169. {
  170. *(uint64_t *)output = (uint64_t)strtoull(str, NULL, 10);
  171. }
  172. // Преобразование строки в double
  173. void convert_to_double(const char *str, void *output)
  174. {
  175. *(double *)output = strtod(str, NULL);
  176. }
  177. // Универсальная функция для разделения строки на лексемы
  178. void split_lexeme(const char *ptr_scpi, void *out_value, size_t element_size, convert_func_type convert_func)
  179. {
  180. uint8_t counter = 0;
  181. // Разделители лексем
  182. const char charSeparator[] = {" "};
  183. char *ptr_lexeme = NULL;
  184. // Указатель для хранения контекста токенизации
  185. char *savePtr;
  186. // Инициализируем функцию
  187. ptr_lexeme = strtok_r((char *)ptr_scpi, charSeparator, &savePtr);
  188. // Ищем лексемы разделенные разделителем
  189. ptr_lexeme = strtok_r(NULL, charSeparator, &savePtr);
  190. // Ищем лексемы строки
  191. while (ptr_lexeme) {
  192. // Проверяем, является ли первый символ лексемы числом
  193. if(('0' <= ptr_lexeme[0]) && (ptr_lexeme[0] <= '9')) {
  194. // Преобразуем строку с числом в число
  195. convert_func(ptr_lexeme, (uint8_t *)out_value + counter * element_size);
  196. counter++;
  197. }
  198. // Ищем лексемы разделенные разделителем
  199. ptr_lexeme = strtok_r(NULL, charSeparator, &savePtr);
  200. }
  201. }