furi-hal-console.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <furi-hal-console.h>
  2. #include <furi-hal-lpuart.h>
  3. #include <stdbool.h>
  4. #include <stm32wbxx_ll_gpio.h>
  5. #include <stm32wbxx_ll_usart.h>
  6. #include <m-string.h>
  7. #include <furi.h>
  8. #define CONSOLE_BAUDRATE 230400
  9. volatile bool furi_hal_console_alive = false;
  10. static void (*irq_cb)(uint8_t ev, uint8_t data);
  11. void furi_hal_console_init() {
  12. LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  13. GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;
  14. GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  15. GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  16. GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  17. GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  18. GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
  19. LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  20. LL_USART_InitTypeDef USART_InitStruct = {0};
  21. USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
  22. USART_InitStruct.BaudRate = CONSOLE_BAUDRATE;
  23. USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  24. USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  25. USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  26. USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  27. USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  28. USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  29. LL_USART_Init(USART1, &USART_InitStruct);
  30. LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2);
  31. LL_USART_EnableFIFO(USART1);
  32. LL_USART_ConfigAsyncMode(USART1);
  33. LL_USART_Enable(USART1);
  34. while(!LL_USART_IsActiveFlag_TEACK(USART1)) ;
  35. LL_USART_EnableIT_RXNE_RXFNE(USART1);
  36. LL_USART_EnableIT_IDLE(USART1);
  37. HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
  38. furi_hal_console_alive = true;
  39. FURI_LOG_I("FuriHalConsole", "Init OK");
  40. }
  41. void furi_hal_usart_init() {
  42. furi_hal_console_alive = false;
  43. }
  44. void furi_hal_usart_set_br(uint32_t baud) {
  45. if (LL_USART_IsEnabled(USART1)) {
  46. // Wait for transfer complete flag
  47. while (!LL_USART_IsActiveFlag_TC(USART1));
  48. LL_USART_Disable(USART1);
  49. uint32_t uartclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE);
  50. LL_USART_SetBaudRate(USART1, uartclk, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, baud);
  51. LL_USART_Enable(USART1);
  52. }
  53. }
  54. void furi_hal_usart_deinit() {
  55. while (!LL_USART_IsActiveFlag_TC(USART1));
  56. furi_hal_usart_set_br(CONSOLE_BAUDRATE);
  57. furi_hal_console_alive = true;
  58. }
  59. void furi_hal_usart_tx(const uint8_t* buffer, size_t buffer_size) {
  60. if (LL_USART_IsEnabled(USART1) == 0)
  61. return;
  62. while(buffer_size > 0) {
  63. while (!LL_USART_IsActiveFlag_TXE(USART1));
  64. LL_USART_TransmitData8(USART1, *buffer);
  65. buffer++;
  66. buffer_size--;
  67. }
  68. }
  69. void furi_hal_usart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)) {
  70. irq_cb = cb;
  71. if (irq_cb == NULL)
  72. NVIC_DisableIRQ(USART1_IRQn);
  73. else
  74. NVIC_EnableIRQ(USART1_IRQn);
  75. }
  76. void USART1_IRQHandler(void) {
  77. if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) {
  78. uint8_t data = LL_USART_ReceiveData8(USART1);
  79. irq_cb(UartIrqEventRXNE, data);
  80. } else if (LL_USART_IsActiveFlag_IDLE(USART1)) {
  81. irq_cb(UartIrqEventIDLE, 0);
  82. LL_USART_ClearFlag_IDLE(USART1);
  83. }
  84. //TODO: more events
  85. }
  86. void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) {
  87. if (!furi_hal_console_alive)
  88. return;
  89. // Transmit data
  90. furi_hal_usart_tx(buffer, buffer_size);
  91. // Wait for TC flag to be raised for last char
  92. while (!LL_USART_IsActiveFlag_TC(USART1));
  93. }
  94. void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) {
  95. if (!furi_hal_console_alive)
  96. return;
  97. // Transmit data
  98. furi_hal_usart_tx(buffer, buffer_size);
  99. // Transmit new line symbols
  100. furi_hal_usart_tx((const uint8_t*)"\r\n", 2);
  101. // Wait for TC flag to be raised for last char
  102. while (!LL_USART_IsActiveFlag_TC(USART1));
  103. }
  104. void furi_hal_console_printf(const char format[], ...) {
  105. string_t string;
  106. va_list args;
  107. va_start(args, format);
  108. string_init_vprintf(string, format, args);
  109. va_end(args);
  110. furi_hal_console_tx((const uint8_t*)string_get_cstr(string), string_size(string));
  111. string_clear(string);
  112. }
  113. void furi_hal_console_puts(const char *data) {
  114. furi_hal_console_tx((const uint8_t*)data, strlen(data));
  115. }