command.c 8.2 KB

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