uart.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "seader_i.h"
  2. #define TAG "SeaderUART"
  3. void seader_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
  4. SeaderUartBridge* seader_uart = (SeaderUartBridge*)context;
  5. if(ev == UartIrqEventRXNE) {
  6. furi_stream_buffer_send(seader_uart->rx_stream, &data, 1, 0);
  7. furi_thread_flags_set(furi_thread_get_id(seader_uart->thread), WorkerEvtRxDone);
  8. }
  9. }
  10. void seader_uart_disable(SeaderUartBridge* seader_uart) {
  11. furi_assert(seader_uart);
  12. furi_thread_flags_set(furi_thread_get_id(seader_uart->thread), WorkerEvtStop);
  13. furi_thread_join(seader_uart->thread);
  14. furi_thread_free(seader_uart->thread);
  15. free(seader_uart);
  16. }
  17. void seader_uart_serial_init(SeaderUartBridge* seader_uart, uint8_t uart_ch) {
  18. UNUSED(seader_uart);
  19. furi_hal_uart_init(uart_ch, 115200);
  20. furi_hal_uart_set_irq_cb(uart_ch, seader_uart_on_irq_cb, seader_uart);
  21. }
  22. void seader_uart_serial_deinit(SeaderUartBridge* seader_uart, uint8_t uart_ch) {
  23. UNUSED(seader_uart);
  24. furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL);
  25. furi_hal_uart_deinit(uart_ch);
  26. }
  27. void seader_uart_set_baudrate(SeaderUartBridge* seader_uart, uint32_t baudrate) {
  28. if(baudrate != 0) {
  29. furi_hal_uart_set_br(seader_uart->cfg.uart_ch, baudrate);
  30. } else {
  31. FURI_LOG_I(TAG, "No baudrate specified");
  32. }
  33. }
  34. size_t seader_uart_process_buffer(Seader* seader, uint8_t* cmd, size_t cmd_len) {
  35. SeaderWorker* seader_worker = seader->worker;
  36. SeaderUartBridge* seader_uart = seader->uart;
  37. if(cmd_len < 2) {
  38. return cmd_len;
  39. }
  40. size_t consumed = 0;
  41. do {
  42. consumed = processCCID(seader_worker, cmd, cmd_len);
  43. if(consumed > 0) {
  44. memset(cmd, 0, consumed);
  45. cmd_len -= consumed;
  46. if(cmd_len > 0) {
  47. memmove(cmd, cmd + consumed, cmd_len);
  48. }
  49. seader_uart->st.rx_cnt += consumed;
  50. /*
  51. memset(display, 0, SEADER_UART_RX_BUF_SIZE);
  52. for (uint8_t i = 0; i < cmd_len; i++) {
  53. snprintf(display+(i*2), sizeof(display), "%02x", cmd[i]);
  54. }
  55. FURI_LOG_I(TAG, "cmd is now %d bytes: %s", cmd_len, display);
  56. */
  57. }
  58. } while(consumed > 0 && cmd_len > 0);
  59. return cmd_len;
  60. }
  61. int32_t seader_uart_worker(void* context) {
  62. Seader* seader = (Seader*)context;
  63. SeaderUartBridge* seader_uart = seader->uart;
  64. memcpy(&seader_uart->cfg, &seader_uart->cfg_new, sizeof(SeaderUartConfig));
  65. seader_uart->rx_stream = furi_stream_buffer_alloc(SEADER_UART_RX_BUF_SIZE, 1);
  66. seader_uart->tx_sem = furi_semaphore_alloc(1, 1);
  67. seader_uart->tx_thread =
  68. furi_thread_alloc_ex("SeaderUartTxWorker", 2 * 1024, seader_uart_tx_thread, seader);
  69. seader_uart_serial_init(seader_uart, seader_uart->cfg.uart_ch);
  70. seader_uart_set_baudrate(seader_uart, seader_uart->cfg.baudrate);
  71. furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
  72. furi_thread_start(seader_uart->tx_thread);
  73. uint8_t cmd[SEADER_UART_RX_BUF_SIZE];
  74. size_t cmd_len = 0;
  75. while(1) {
  76. uint32_t events =
  77. furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
  78. furi_check(!(events & FuriFlagError));
  79. if(events & WorkerEvtStop) {
  80. memset(cmd, 0, cmd_len);
  81. cmd_len = 0;
  82. break;
  83. }
  84. if(events & WorkerEvtRxDone) {
  85. size_t len = furi_stream_buffer_receive(
  86. seader_uart->rx_stream, seader_uart->rx_buf, SEADER_UART_RX_BUF_SIZE, 0);
  87. if(len > 0) {
  88. furi_delay_ms(5); //WTF
  89. /*
  90. char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
  91. for (uint8_t i = 0; i < len; i++) {
  92. snprintf(display+(i*2), sizeof(display), "%02x", seader_uart->rx_buf[i]);
  93. }
  94. FURI_LOG_I(TAG, "RECV %d bytes: %s", len, display);
  95. */
  96. if(cmd_len + len > SEADER_UART_RX_BUF_SIZE) {
  97. FURI_LOG_I(TAG, "OVERFLOW: %d + %d", cmd_len, len);
  98. memset(cmd, 0, cmd_len);
  99. cmd_len = 0;
  100. }
  101. memcpy(cmd + cmd_len, seader_uart->rx_buf, len);
  102. cmd_len += len;
  103. cmd_len = seader_uart_process_buffer(seader, cmd, cmd_len);
  104. }
  105. }
  106. }
  107. seader_uart_serial_deinit(seader_uart, seader_uart->cfg.uart_ch);
  108. furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtTxStop);
  109. furi_thread_join(seader_uart->tx_thread);
  110. furi_thread_free(seader_uart->tx_thread);
  111. furi_stream_buffer_free(seader_uart->rx_stream);
  112. furi_semaphore_free(seader_uart->tx_sem);
  113. return 0;
  114. }
  115. SeaderUartBridge* seader_uart_enable(SeaderUartConfig* cfg, Seader* seader) {
  116. SeaderUartBridge* seader_uart = malloc(sizeof(SeaderUartBridge));
  117. memcpy(&(seader_uart->cfg_new), cfg, sizeof(SeaderUartConfig));
  118. seader_uart->thread =
  119. furi_thread_alloc_ex("SeaderUartWorker", 5 * 1024, seader_uart_worker, seader);
  120. furi_thread_start(seader_uart->thread);
  121. return seader_uart;
  122. }
  123. int32_t seader_uart_tx_thread(void* context) {
  124. Seader* seader = (Seader*)context;
  125. SeaderUartBridge* seader_uart = seader->uart;
  126. while(1) {
  127. uint32_t events =
  128. furi_thread_flags_wait(WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
  129. furi_check(!(events & FuriFlagError));
  130. if(events & WorkerEvtTxStop) break;
  131. if(events & WorkerEvtSamRx) {
  132. if(seader_uart->tx_len > 0) {
  133. /*
  134. char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
  135. for(uint8_t i = 0; i < seader_uart->tx_len; i++) {
  136. snprintf(display + (i * 2), sizeof(display), "%02x", seader_uart->tx_buf[i]);
  137. }
  138. FURI_LOG_I(TAG, "SEND %d bytes: %s", seader_uart->tx_len, display);
  139. */
  140. seader_uart->st.tx_cnt += seader_uart->tx_len;
  141. furi_hal_uart_tx(
  142. seader_uart->cfg.uart_ch, seader_uart->tx_buf, seader_uart->tx_len);
  143. }
  144. }
  145. }
  146. return 0;
  147. }
  148. void seader_uart_get_config(SeaderUartBridge* seader_uart, SeaderUartConfig* cfg) {
  149. furi_assert(seader_uart);
  150. furi_assert(cfg);
  151. memcpy(cfg, &(seader_uart->cfg_new), sizeof(SeaderUartConfig));
  152. }
  153. void seader_uart_get_state(SeaderUartBridge* seader_uart, SeaderUartState* st) {
  154. furi_assert(seader_uart);
  155. furi_assert(st);
  156. memcpy(st, &(seader_uart->st), sizeof(SeaderUartState));
  157. }
  158. SeaderUartBridge* seader_uart_alloc(Seader* seader) {
  159. SeaderUartConfig cfg = {.uart_ch = FuriHalUartIdLPUART1, .baudrate = 115200};
  160. SeaderUartState uart_state;
  161. SeaderUartBridge* seader_uart;
  162. FURI_LOG_I(TAG, "Enable UART");
  163. seader_uart = seader_uart_enable(&cfg, seader);
  164. seader_uart_get_config(seader_uart, &cfg);
  165. seader_uart_get_state(seader_uart, &uart_state);
  166. return seader_uart;
  167. }
  168. void seader_uart_free(SeaderUartBridge* seader_uart) {
  169. seader_uart_disable(seader_uart);
  170. }