ksp-serial.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Copyright (C) 2023 Daniele Lacamera <root@danielinux.net>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <unicore-mx/stm32/memorymap.h>
  18. #include <unicore-mx/stm32/rcc.h>
  19. #include <unicore-mx/stm32/gpio.h>
  20. #include <unicore-mx/stm32/usart.h>
  21. #include <unicore-mx/stm32/f7/nvic.h>
  22. #include <stddef.h>
  23. #include <string.h>
  24. #include "systick.h"
  25. #include "task.h"
  26. #include "ksp-serial.h"
  27. static void ksp_serial_poll(uint32_t ev, void *arg);
  28. static void ksp_serial_init(void);
  29. static uint32_t last_poll = 0;
  30. static volatile uint8_t buf[4096]; /* Reserve a page for serial comm */
  31. static volatile uint32_t buf_count = 0;
  32. static uint8_t kspio_rxlen;
  33. static int kspio_busy;
  34. #define KSP_UART USART1
  35. const char ksp_name[] = "KSPSerial";
  36. struct task ksp_task = {
  37. .init = ksp_serial_init,
  38. .run = ksp_serial_poll,
  39. .events = EV_SERIAL,
  40. .name = ksp_name
  41. };
  42. static uint8_t cur_vdata_buf[204];
  43. vesselData_t *cur_vdata = (vesselData_t *)(cur_vdata_buf + 3);
  44. const char vesselDataName[][18] = {
  45. "id", //1
  46. "AP", //2
  47. "PE", //3
  48. "SemiMajorAxis", //4
  49. "SemiMinorAxis", //5
  50. "VVI", //6
  51. "e", //7
  52. "inc", //8
  53. "G", //9
  54. "TAp", //10
  55. "TPe", //11
  56. "TrueAnomaly", //12
  57. "Density", //13
  58. "t period", //14
  59. "RAlt", //15
  60. "Alt", //16
  61. "Vsurf", //17
  62. "Lat", //18
  63. "Lon", //19
  64. "LiquidFuelTot", //20
  65. "LiquidFuel", //21
  66. "OxidizerTot", //22
  67. "Oxidizer", //23
  68. "EChargeTot", //24
  69. "ECharge", //25
  70. "MonoPropTot", //26
  71. "MonoProp", //27
  72. "IntakeAirTot", //28
  73. "IntakeAir", //29
  74. "SolidFuelTot", //30
  75. "SolidFuel", //31
  76. "XenonGasTot", //32
  77. "XenonGas", //33
  78. "LiquidFuelTotS", //34
  79. "LiquidFuelS", //35
  80. "OxidizerTotS", //36
  81. "OxidizerS", //37
  82. "MissionTime", //38
  83. "deltaTime", //39
  84. "VOrbit", //40
  85. "MNTime", //41
  86. "MNDeltaV", //42
  87. "Pitch", //43
  88. "Roll", //44
  89. "Heading", //45
  90. };
  91. uint8_t ksp_serial_checksum(uint8_t *bytes, uint8_t sz)
  92. {
  93. uint8_t chk = sz;
  94. uint8_t i;
  95. for (i = 0; i < sz; i++) {
  96. chk ^= bytes[i];
  97. }
  98. return chk;
  99. }
  100. void ksp_serial_init(void)
  101. {
  102. last_poll = jiffies;
  103. rcc_periph_clock_enable(RCC_USART1);
  104. rcc_periph_clock_enable(RCC_GPIOA);
  105. rcc_periph_clock_enable(RCC_GPIOB);
  106. gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9);
  107. gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO7);
  108. gpio_set_af(GPIOA, GPIO_AF7, GPIO9);
  109. gpio_set_af(GPIOB, GPIO_AF7, GPIO7);
  110. /* Set up USART/UART parameters using the unicore-mx helper functions */
  111. usart_enable_rx_interrupt(KSP_UART);
  112. usart_set_baudrate(KSP_UART, 115200);
  113. usart_set_databits(KSP_UART, 8);
  114. usart_set_stopbits(KSP_UART, USART_STOPBITS_1);
  115. usart_set_mode(KSP_UART, USART_MODE_TX_RX);
  116. usart_set_parity(KSP_UART, USART_PARITY_NONE);
  117. usart_set_flow_control(KSP_UART, USART_FLOWCONTROL_NONE);
  118. usart_enable_rx_interrupt(KSP_UART);
  119. USART_CR1(KSP_UART) &= ~(USART_CR1_TCIE);
  120. nvic_enable_irq(NVIC_USART1_IRQ);
  121. usart_enable(KSP_UART);
  122. }
  123. void kspserial_setup(void)
  124. {
  125. register_task(&ksp_task);
  126. }
  127. void ksp_serial_send(const void *data, uint8_t len)
  128. {
  129. int i;
  130. unsigned char *bytes = (unsigned char *)data;
  131. uint8_t chk = ksp_serial_checksum(bytes, len);
  132. usart_send_blocking(KSP_UART, 0xBE);
  133. usart_send_blocking(KSP_UART, 0xEF);
  134. usart_send_blocking(KSP_UART, len);
  135. for(i = 0; i < len; i++)
  136. usart_send_blocking(KSP_UART, bytes[i]);
  137. usart_send_blocking(KSP_UART, chk);
  138. }
  139. static void ksp_serial_handshake(void)
  140. {
  141. handShakePacket_t hs;
  142. hs.id = 0;
  143. hs.M1 = 3;
  144. hs.M2 = 1;
  145. hs.M3 = 4;
  146. ksp_serial_send(&hs, sizeof(hs));
  147. }
  148. static void ksp_serial_rxdata(void)
  149. {
  150. uint8_t chk_exp, chk_rx;
  151. if (buf[2] == sizeof(vesselData_t)) {
  152. chk_rx = buf[sizeof(vesselData_t) + 3];
  153. chk_exp = ksp_serial_checksum(buf + 3, buf[2]);
  154. if (chk_rx != chk_exp) {
  155. return;
  156. }
  157. memcpy(cur_vdata_buf, buf, buf[2] + 3);
  158. memset(buf, 0, sizeof(buf));
  159. buf_count = 0;
  160. trigger_event(EV_VESSELDATA);
  161. }
  162. }
  163. static void ksp_serial_poll(uint32_t ev, void *arg)
  164. {
  165. if (buf_count == 0) {
  166. clear_event(EV_SERIAL);
  167. return;
  168. }
  169. while((buf_count < (buf[2] + 4)) && usart_is_recv_ready(KSP_UART)) {
  170. buf[buf_count++] = usart_recv(KSP_UART);
  171. }
  172. if (buf_count < buf[2] + 4)
  173. return;
  174. if (buf[3] == (uint8_t)0) {
  175. ksp_serial_handshake();
  176. }
  177. else if (buf[3] == (uint8_t)1) {
  178. ksp_serial_rxdata();
  179. }
  180. clear_event(EV_SERIAL);
  181. buf_count = 0;
  182. usart_enable_rx_interrupt(KSP_UART);
  183. kspio_busy = 0;
  184. last_poll = jiffies;
  185. }
  186. #include <unicore-mx/stm32/usart.h>
  187. #include "task.h"
  188. void isr_usart1(void)
  189. {
  190. uint16_t rx;
  191. usart_clear_rx_interrupt(KSP_UART);
  192. usart_clear_tx_interrupt(KSP_UART);
  193. if (usart_is_recv_ready(KSP_UART)) {
  194. rx = usart_recv(KSP_UART);
  195. buf[buf_count++] = (unsigned char)(rx & 0xFF);
  196. if (kspio_busy) {
  197. trigger_event(EV_SERIAL);
  198. return;
  199. }
  200. if ((buf_count == 1) && (buf[0] != 0xBE)) {
  201. buf_count = 0;
  202. return;
  203. }
  204. if ((buf_count == 2) && (buf[1] != 0xEF)) {
  205. buf_count = 0;
  206. return;
  207. }
  208. if (buf_count == 3) {
  209. kspio_rxlen = buf[2];
  210. kspio_busy++;
  211. trigger_event(EV_SERIAL);
  212. return;
  213. }
  214. }
  215. }