diff options
author | Nikolay Minaylov <nm29719@gmail.com> | 2021-10-26 21:41:56 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-26 21:41:56 +0300 |
commit | 732b9546fc29d0eee07d2230e52d035b32b89c81 (patch) | |
tree | 1d4bb55c0a670e351ed097a9db92684dbc40d600 /firmware | |
parent | fae8d8f23ceb971cb08119d0dc8de48a06091a13 (diff) |
[FL-1984] USB-UART improvements and fixes (#785)
* [FL-1984] USB-UART fixes
* FuriHal: fix SOF wait on CDC0
* FuriHal: fixed stuck in UART IRQ with ORE event
Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-clock.c | 2 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-console.c | 99 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-console.h | 16 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-lpuart.c | 105 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-lpuart.h | 24 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-uart.c | 201 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-uart.h | 29 | ||||
-rw-r--r-- | firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c | 10 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-clock.c | 2 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-console.c | 99 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-console.h | 16 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-lpuart.c | 105 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-lpuart.h | 24 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-uart.c | 197 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-uart.h | 29 | ||||
-rw-r--r-- | firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c | 10 | ||||
-rw-r--r-- | firmware/targets/furi-hal-include/furi-hal.h | 2 |
17 files changed, 503 insertions, 467 deletions
diff --git a/firmware/targets/f6/furi-hal/furi-hal-clock.c b/firmware/targets/f6/furi-hal/furi-hal-clock.c index 2544c769..fd4899d4 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-clock.c +++ b/firmware/targets/f6/furi-hal/furi-hal-clock.c @@ -84,6 +84,7 @@ void furi_hal_clock_init() { LL_RCC_EnableRTC(); LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); @@ -117,6 +118,7 @@ void furi_hal_clock_init() { // APB1 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); // APB2 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); diff --git a/firmware/targets/f6/furi-hal/furi-hal-console.c b/firmware/targets/f6/furi-hal/furi-hal-console.c index 552f9e77..ffe340b9 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-console.c +++ b/firmware/targets/f6/furi-hal/furi-hal-console.c @@ -1,5 +1,5 @@ #include <furi-hal-console.h> -#include <furi-hal-lpuart.h> +#include <furi-hal-uart.h> #include <stdbool.h> #include <stm32wbxx_ll_gpio.h> @@ -12,98 +12,23 @@ volatile bool furi_hal_console_alive = false; -static void (*irq_cb)(uint8_t ev, uint8_t data); - void furi_hal_console_init() { - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_7; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - LL_USART_InitTypeDef USART_InitStruct = {0}; - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; - USART_InitStruct.BaudRate = CONSOLE_BAUDRATE; - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; - USART_InitStruct.StopBits = LL_USART_STOPBITS_1; - USART_InitStruct.Parity = LL_USART_PARITY_NONE; - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; - LL_USART_Init(USART1, &USART_InitStruct); - LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); - LL_USART_EnableFIFO(USART1); - LL_USART_ConfigAsyncMode(USART1); - - LL_USART_Enable(USART1); - - while(!LL_USART_IsActiveFlag_TEACK(USART1)) ; - - LL_USART_EnableIT_RXNE_RXFNE(USART1); - LL_USART_EnableIT_IDLE(USART1); - HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); - + furi_hal_uart_init(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); furi_hal_console_alive = true; FURI_LOG_I("FuriHalConsole", "Init OK"); } -void furi_hal_usart_init() { - furi_hal_console_alive = false; -} - -void furi_hal_usart_set_br(uint32_t baud) { - if (LL_USART_IsEnabled(USART1)) { - // Wait for transfer complete flag - while (!LL_USART_IsActiveFlag_TC(USART1)); - LL_USART_Disable(USART1); - uint32_t uartclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); - LL_USART_SetBaudRate(USART1, uartclk, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, baud); - LL_USART_Enable(USART1); - } -} - -void furi_hal_usart_deinit() { +void furi_hal_console_enable() { + furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL); while (!LL_USART_IsActiveFlag_TC(USART1)); - furi_hal_usart_set_br(CONSOLE_BAUDRATE); + furi_hal_uart_set_br(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); furi_hal_console_alive = true; } -void furi_hal_usart_tx(const uint8_t* buffer, size_t buffer_size) { - if (LL_USART_IsEnabled(USART1) == 0) - return; - - while(buffer_size > 0) { - while (!LL_USART_IsActiveFlag_TXE(USART1)); - - LL_USART_TransmitData8(USART1, *buffer); - - buffer++; - buffer_size--; - } -} - -void furi_hal_usart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)) { - irq_cb = cb; - if (irq_cb == NULL) - NVIC_DisableIRQ(USART1_IRQn); - else - NVIC_EnableIRQ(USART1_IRQn); -} - -void USART1_IRQHandler(void) { - if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) { - uint8_t data = LL_USART_ReceiveData8(USART1); - irq_cb(UartIrqEventRXNE, data); - } else if (LL_USART_IsActiveFlag_IDLE(USART1)) { - irq_cb(UartIrqEventIDLE, 0); - LL_USART_ClearFlag_IDLE(USART1); - } - - //TODO: more events +void furi_hal_console_disable() { + while (!LL_USART_IsActiveFlag_TC(USART1)); + furi_hal_console_alive = false; } void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { @@ -111,7 +36,7 @@ void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { return; // Transmit data - furi_hal_usart_tx(buffer, buffer_size); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); } @@ -121,9 +46,9 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size return; // Transmit data - furi_hal_usart_tx(buffer, buffer_size); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Transmit new line symbols - furi_hal_usart_tx((const uint8_t*)"\r\n", 2); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); } @@ -140,4 +65,4 @@ void furi_hal_console_printf(const char format[], ...) { void furi_hal_console_puts(const char *data) { furi_hal_console_tx((const uint8_t*)data, strlen(data)); -}
\ No newline at end of file +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-console.h b/firmware/targets/f6/furi-hal/furi-hal-console.h index 013653ba..4c10d81e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-console.h +++ b/firmware/targets/f6/furi-hal/furi-hal-console.h @@ -15,6 +15,10 @@ typedef enum { void furi_hal_console_init(); +void furi_hal_console_enable(); + +void furi_hal_console_disable(); + void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size); @@ -29,18 +33,6 @@ void furi_hal_console_printf(const char format[], ...); void furi_hal_console_puts(const char* data); - -void furi_hal_usart_init(); - -void furi_hal_usart_deinit(); - -void furi_hal_usart_set_br(uint32_t baud); - -void furi_hal_usart_tx(const uint8_t* buffer, size_t buffer_size); - -void furi_hal_usart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)); - - #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/furi-hal/furi-hal-lpuart.c b/firmware/targets/f6/furi-hal/furi-hal-lpuart.c deleted file mode 100644 index 31aa8b86..00000000 --- a/firmware/targets/f6/furi-hal/furi-hal-lpuart.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <furi-hal-lpuart.h> -#include <stdbool.h> -#include <stm32wbxx_ll_gpio.h> -#include <stm32wbxx_ll_lpuart.h> - -#include <furi.h> - -static void (*irq_cb)(uint8_t ev, uint8_t data); - -void furi_hal_lpuart_init() { - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = PC0_Pin|PC1_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_8; - LL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); - LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); - - LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; - LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; - LPUART_InitStruct.BaudRate = 115200; - LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; - LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; - LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; - LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; - LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; - LL_LPUART_Init(LPUART1, &LPUART_InitStruct); - LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); - LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); - LL_LPUART_EnableFIFO(LPUART1); - - LL_LPUART_Enable(LPUART1); - - while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))); - - LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); - LL_LPUART_EnableIT_IDLE(LPUART1); - HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0); - - FURI_LOG_I("FuriHalLpUart", "Init OK"); -} - -void furi_hal_lpuart_set_br(uint32_t baud) { - if (LL_LPUART_IsEnabled(LPUART1)) { - // Wait for transfer complete flag - while (!LL_LPUART_IsActiveFlag_TC(LPUART1)); - LL_LPUART_Disable(LPUART1); - uint32_t uartclk = LL_RCC_GetLPUARTClockFreq(LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1)); - if (uartclk/baud > 4095) { - LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV32); - LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV32, baud); - } else { - LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV1); - LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV1, baud); - } - - LL_LPUART_Enable(LPUART1); - } -} - -void furi_hal_lpuart_deinit() { - furi_hal_lpuart_set_irq_cb(NULL); - LL_GPIO_SetPinMode(GPIOC, PC0_Pin, LL_GPIO_MODE_ANALOG); - LL_GPIO_SetPinMode(GPIOC, PC1_Pin, LL_GPIO_MODE_ANALOG); - LL_LPUART_Disable(LPUART1); - LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_LPUART1); -} - -void furi_hal_lpuart_tx(const uint8_t* buffer, size_t buffer_size) { - if (LL_LPUART_IsEnabled(LPUART1) == 0) - return; - - while(buffer_size > 0) { - while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)); - - LL_LPUART_TransmitData8(LPUART1, *buffer); - - buffer++; - buffer_size--; - } -} - -void furi_hal_lpuart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)) { - irq_cb = cb; - if (irq_cb == NULL) - NVIC_DisableIRQ(LPUART1_IRQn); - else - NVIC_EnableIRQ(LPUART1_IRQn); -} - -void LPUART1_IRQHandler(void) { - if (LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) { - uint8_t data = LL_LPUART_ReceiveData8(LPUART1); - irq_cb(UartIrqEventRXNE, data); - } else if (LL_LPUART_IsActiveFlag_IDLE(LPUART1)) { - irq_cb(UartIrqEventIDLE, 0); - LL_LPUART_ClearFlag_IDLE(LPUART1); - } - - //TODO: more events -} diff --git a/firmware/targets/f6/furi-hal/furi-hal-lpuart.h b/firmware/targets/f6/furi-hal/furi-hal-lpuart.h deleted file mode 100644 index 118a9a9c..00000000 --- a/firmware/targets/f6/furi-hal/furi-hal-lpuart.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include <stddef.h> -#include <stdint.h> -#include "furi-hal-console.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -void furi_hal_lpuart_init(); - -void furi_hal_lpuart_deinit(); - -void furi_hal_lpuart_set_br(uint32_t baud); - -void furi_hal_lpuart_tx(const uint8_t* buffer, size_t buffer_size); - -void furi_hal_lpuart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/f6/furi-hal/furi-hal-uart.c b/firmware/targets/f6/furi-hal/furi-hal-uart.c new file mode 100644 index 00000000..ff2d94a7 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-uart.c @@ -0,0 +1,201 @@ +#include <furi-hal-uart.h> +#include <stdbool.h> +#include <stm32wbxx_ll_lpuart.h> +#include <stm32wbxx_ll_usart.h> +#include <furi-hal-resources.h> + +#include <furi.h> + +static void (*irq_cb[2])(uint8_t ev, uint8_t data); + +static void furi_hal_usart_init(uint32_t baud) { + hal_gpio_init_ex( + &gpio_usart_tx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + hal_gpio_init_ex( + &gpio_usart_rx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + + LL_USART_InitTypeDef USART_InitStruct = {0}; + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = baud; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); + LL_USART_EnableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + LL_USART_Enable(USART1); + + while(!LL_USART_IsActiveFlag_TEACK(USART1)); + + LL_USART_EnableIT_RXNE_RXFNE(USART1); + LL_USART_EnableIT_IDLE(USART1); + HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); +} + +static void furi_hal_lpuart_init(uint32_t baud) { + hal_gpio_init_ex( + &gpio_ext_pc0, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn8LPUART1); + hal_gpio_init_ex( + &gpio_ext_pc1, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn8LPUART1); + + LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; + LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct.BaudRate = 115200; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; + LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_EnableFIFO(LPUART1); + + LL_LPUART_Enable(LPUART1); + + while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))); + + furi_hal_uart_set_br(FuriHalUartIdLPUART1, baud); + + LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); + LL_LPUART_EnableIT_IDLE(LPUART1); + HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0); +} + +void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) { + if (ch == FuriHalUartIdLPUART1) + furi_hal_lpuart_init(baud); + else if (ch == FuriHalUartIdUSART1) + furi_hal_usart_init(baud); +} + +void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) { + if (ch == FuriHalUartIdUSART1) { + if (LL_USART_IsEnabled(USART1)) { + // Wait for transfer complete flag + while (!LL_USART_IsActiveFlag_TC(USART1)); + LL_USART_Disable(USART1); + uint32_t uartclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); + LL_USART_SetBaudRate(USART1, uartclk, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, baud); + LL_USART_Enable(USART1); + } + } else if (ch == FuriHalUartIdLPUART1) { + if (LL_LPUART_IsEnabled(LPUART1)) { + // Wait for transfer complete flag + while (!LL_LPUART_IsActiveFlag_TC(LPUART1)); + LL_LPUART_Disable(LPUART1); + uint32_t uartclk = LL_RCC_GetLPUARTClockFreq(LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1)); + if (uartclk/baud > 4095) { + LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV32); + LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV32, baud); + } else { + LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV1); + LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV1, baud); + } + LL_LPUART_Enable(LPUART1); + } + } +} + +void furi_hal_uart_deinit(FuriHalUartId ch) { + furi_hal_uart_set_irq_cb(ch, NULL); + if (ch == FuriHalUartIdUSART1) { + LL_USART_Disable(USART1); + hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (ch == FuriHalUartIdLPUART1) { + LL_LPUART_Disable(LPUART1); + hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } +} + +void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size) { + if (ch == FuriHalUartIdUSART1) { + if (LL_USART_IsEnabled(USART1) == 0) + return; + + while(buffer_size > 0) { + while (!LL_USART_IsActiveFlag_TXE(USART1)); + + LL_USART_TransmitData8(USART1, *buffer); + buffer++; + buffer_size--; + } + + } else if (ch == FuriHalUartIdLPUART1) { + if (LL_LPUART_IsEnabled(LPUART1) == 0) + return; + + while(buffer_size > 0) { + while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)); + + LL_LPUART_TransmitData8(LPUART1, *buffer); + + buffer++; + buffer_size--; + } + } +} + +void furi_hal_uart_set_irq_cb(FuriHalUartId ch, void (*cb)(UartIrqEvent ev, uint8_t data)) { + if (cb == NULL) { + if (ch == FuriHalUartIdUSART1) + NVIC_DisableIRQ(USART1_IRQn); + else if (ch == FuriHalUartIdLPUART1) + NVIC_DisableIRQ(LPUART1_IRQn); + irq_cb[ch] = cb; + } else { + irq_cb[ch] = cb; + if (ch == FuriHalUartIdUSART1) + NVIC_EnableIRQ(USART1_IRQn); + else if (ch == FuriHalUartIdLPUART1) + NVIC_EnableIRQ(LPUART1_IRQn); + } +} + +void LPUART1_IRQHandler(void) { + if (LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) { + uint8_t data = LL_LPUART_ReceiveData8(LPUART1); + irq_cb[FuriHalUartIdLPUART1](UartIrqEventRXNE, data); + } else if (LL_LPUART_IsActiveFlag_IDLE(LPUART1)) { + irq_cb[FuriHalUartIdLPUART1](UartIrqEventIDLE, 0); + LL_LPUART_ClearFlag_IDLE(LPUART1); + } else if (LL_LPUART_IsActiveFlag_ORE(LPUART1)) { + LL_LPUART_ClearFlag_ORE(LPUART1); + } + //TODO: more events +} + +void USART1_IRQHandler(void) { + if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) { + uint8_t data = LL_USART_ReceiveData8(USART1); + irq_cb[FuriHalUartIdUSART1](UartIrqEventRXNE, data); + } else if (LL_USART_IsActiveFlag_IDLE(USART1)) { + irq_cb[FuriHalUartIdUSART1](UartIrqEventIDLE, 0); + LL_USART_ClearFlag_IDLE(USART1); + } else if (LL_USART_IsActiveFlag_ORE(USART1)) { + LL_USART_ClearFlag_ORE(USART1); + } +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-uart.h b/firmware/targets/f6/furi-hal/furi-hal-uart.h new file mode 100644 index 00000000..6be156b7 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-uart.h @@ -0,0 +1,29 @@ +#pragma once + +#include <stddef.h> +#include <stdint.h> +#include "furi-hal-console.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriHalUartIdUSART1, + FuriHalUartIdLPUART1, +} FuriHalUartId; + + +void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud); + +void furi_hal_uart_deinit(FuriHalUartId ch); + +void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud); + +void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size); + +void furi_hal_uart_set_irq_cb(FuriHalUartId ch, void (*cb)(UartIrqEvent ev, uint8_t data)); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c index e643fe57..9386b100 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c +++ b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c @@ -7,12 +7,12 @@ #include "usb_cdc.h" #define CDC0_RXD_EP 0x01 -#define CDC0_TXD_EP 0x82 -#define CDC0_NTF_EP 0x83 +#define CDC0_TXD_EP 0x81 +#define CDC0_NTF_EP 0x82 -#define CDC1_RXD_EP 0x04 -#define CDC1_TXD_EP 0x85 -#define CDC1_NTF_EP 0x86 +#define CDC1_RXD_EP 0x03 +#define CDC1_TXD_EP 0x83 +#define CDC1_NTF_EP 0x84 #define CDC_NTF_SZ 0x08 diff --git a/firmware/targets/f7/furi-hal/furi-hal-clock.c b/firmware/targets/f7/furi-hal/furi-hal-clock.c index 2544c769..fd4899d4 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-clock.c +++ b/firmware/targets/f7/furi-hal/furi-hal-clock.c @@ -84,6 +84,7 @@ void furi_hal_clock_init() { LL_RCC_EnableRTC(); LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48); @@ -117,6 +118,7 @@ void furi_hal_clock_init() { // APB1 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); // APB2 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); diff --git a/firmware/targets/f7/furi-hal/furi-hal-console.c b/firmware/targets/f7/furi-hal/furi-hal-console.c index 552f9e77..ffe340b9 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-console.c +++ b/firmware/targets/f7/furi-hal/furi-hal-console.c @@ -1,5 +1,5 @@ #include <furi-hal-console.h> -#include <furi-hal-lpuart.h> +#include <furi-hal-uart.h> #include <stdbool.h> #include <stm32wbxx_ll_gpio.h> @@ -12,98 +12,23 @@ volatile bool furi_hal_console_alive = false; -static void (*irq_cb)(uint8_t ev, uint8_t data); - void furi_hal_console_init() { - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_7; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - LL_USART_InitTypeDef USART_InitStruct = {0}; - USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; - USART_InitStruct.BaudRate = CONSOLE_BAUDRATE; - USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; - USART_InitStruct.StopBits = LL_USART_STOPBITS_1; - USART_InitStruct.Parity = LL_USART_PARITY_NONE; - USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; - USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; - USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; - LL_USART_Init(USART1, &USART_InitStruct); - LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); - LL_USART_EnableFIFO(USART1); - LL_USART_ConfigAsyncMode(USART1); - - LL_USART_Enable(USART1); - - while(!LL_USART_IsActiveFlag_TEACK(USART1)) ; - - LL_USART_EnableIT_RXNE_RXFNE(USART1); - LL_USART_EnableIT_IDLE(USART1); - HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); - + furi_hal_uart_init(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); furi_hal_console_alive = true; FURI_LOG_I("FuriHalConsole", "Init OK"); } -void furi_hal_usart_init() { - furi_hal_console_alive = false; -} - -void furi_hal_usart_set_br(uint32_t baud) { - if (LL_USART_IsEnabled(USART1)) { - // Wait for transfer complete flag - while (!LL_USART_IsActiveFlag_TC(USART1)); - LL_USART_Disable(USART1); - uint32_t uartclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); - LL_USART_SetBaudRate(USART1, uartclk, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, baud); - LL_USART_Enable(USART1); - } -} - -void furi_hal_usart_deinit() { +void furi_hal_console_enable() { + furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL); while (!LL_USART_IsActiveFlag_TC(USART1)); - furi_hal_usart_set_br(CONSOLE_BAUDRATE); + furi_hal_uart_set_br(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); furi_hal_console_alive = true; } -void furi_hal_usart_tx(const uint8_t* buffer, size_t buffer_size) { - if (LL_USART_IsEnabled(USART1) == 0) - return; - - while(buffer_size > 0) { - while (!LL_USART_IsActiveFlag_TXE(USART1)); - - LL_USART_TransmitData8(USART1, *buffer); - - buffer++; - buffer_size--; - } -} - -void furi_hal_usart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)) { - irq_cb = cb; - if (irq_cb == NULL) - NVIC_DisableIRQ(USART1_IRQn); - else - NVIC_EnableIRQ(USART1_IRQn); -} - -void USART1_IRQHandler(void) { - if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) { - uint8_t data = LL_USART_ReceiveData8(USART1); - irq_cb(UartIrqEventRXNE, data); - } else if (LL_USART_IsActiveFlag_IDLE(USART1)) { - irq_cb(UartIrqEventIDLE, 0); - LL_USART_ClearFlag_IDLE(USART1); - } - - //TODO: more events +void furi_hal_console_disable() { + while (!LL_USART_IsActiveFlag_TC(USART1)); + furi_hal_console_alive = false; } void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { @@ -111,7 +36,7 @@ void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { return; // Transmit data - furi_hal_usart_tx(buffer, buffer_size); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); } @@ -121,9 +46,9 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size return; // Transmit data - furi_hal_usart_tx(buffer, buffer_size); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Transmit new line symbols - furi_hal_usart_tx((const uint8_t*)"\r\n", 2); + furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); } @@ -140,4 +65,4 @@ void furi_hal_console_printf(const char format[], ...) { void furi_hal_console_puts(const char *data) { furi_hal_console_tx((const uint8_t*)data, strlen(data)); -}
\ No newline at end of file +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-console.h b/firmware/targets/f7/furi-hal/furi-hal-console.h index 013653ba..4c10d81e 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-console.h +++ b/firmware/targets/f7/furi-hal/furi-hal-console.h @@ -15,6 +15,10 @@ typedef enum { void furi_hal_console_init(); +void furi_hal_console_enable(); + +void furi_hal_console_disable(); + void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size); @@ -29,18 +33,6 @@ void furi_hal_console_printf(const char format[], ...); void furi_hal_console_puts(const char* data); - -void furi_hal_usart_init(); - -void furi_hal_usart_deinit(); - -void furi_hal_usart_set_br(uint32_t baud); - -void furi_hal_usart_tx(const uint8_t* buffer, size_t buffer_size); - -void furi_hal_usart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)); - - #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-lpuart.c b/firmware/targets/f7/furi-hal/furi-hal-lpuart.c deleted file mode 100644 index 31aa8b86..00000000 --- a/firmware/targets/f7/furi-hal/furi-hal-lpuart.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <furi-hal-lpuart.h> -#include <stdbool.h> -#include <stm32wbxx_ll_gpio.h> -#include <stm32wbxx_ll_lpuart.h> - -#include <furi.h> - -static void (*irq_cb)(uint8_t ev, uint8_t data); - -void furi_hal_lpuart_init() { - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = PC0_Pin|PC1_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_8; - LL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); - LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); - - LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; - LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; - LPUART_InitStruct.BaudRate = 115200; - LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; - LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; - LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; - LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; - LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; - LL_LPUART_Init(LPUART1, &LPUART_InitStruct); - LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); - LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); - LL_LPUART_EnableFIFO(LPUART1); - - LL_LPUART_Enable(LPUART1); - - while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))); - - LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); - LL_LPUART_EnableIT_IDLE(LPUART1); - HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0); - - FURI_LOG_I("FuriHalLpUart", "Init OK"); -} - -void furi_hal_lpuart_set_br(uint32_t baud) { - if (LL_LPUART_IsEnabled(LPUART1)) { - // Wait for transfer complete flag - while (!LL_LPUART_IsActiveFlag_TC(LPUART1)); - LL_LPUART_Disable(LPUART1); - uint32_t uartclk = LL_RCC_GetLPUARTClockFreq(LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1)); - if (uartclk/baud > 4095) { - LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV32); - LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV32, baud); - } else { - LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV1); - LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV1, baud); - } - - LL_LPUART_Enable(LPUART1); - } -} - -void furi_hal_lpuart_deinit() { - furi_hal_lpuart_set_irq_cb(NULL); - LL_GPIO_SetPinMode(GPIOC, PC0_Pin, LL_GPIO_MODE_ANALOG); - LL_GPIO_SetPinMode(GPIOC, PC1_Pin, LL_GPIO_MODE_ANALOG); - LL_LPUART_Disable(LPUART1); - LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_LPUART1); -} - -void furi_hal_lpuart_tx(const uint8_t* buffer, size_t buffer_size) { - if (LL_LPUART_IsEnabled(LPUART1) == 0) - return; - - while(buffer_size > 0) { - while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)); - - LL_LPUART_TransmitData8(LPUART1, *buffer); - - buffer++; - buffer_size--; - } -} - -void furi_hal_lpuart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)) { - irq_cb = cb; - if (irq_cb == NULL) - NVIC_DisableIRQ(LPUART1_IRQn); - else - NVIC_EnableIRQ(LPUART1_IRQn); -} - -void LPUART1_IRQHandler(void) { - if (LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) { - uint8_t data = LL_LPUART_ReceiveData8(LPUART1); - irq_cb(UartIrqEventRXNE, data); - } else if (LL_LPUART_IsActiveFlag_IDLE(LPUART1)) { - irq_cb(UartIrqEventIDLE, 0); - LL_LPUART_ClearFlag_IDLE(LPUART1); - } - - //TODO: more events -} diff --git a/firmware/targets/f7/furi-hal/furi-hal-lpuart.h b/firmware/targets/f7/furi-hal/furi-hal-lpuart.h deleted file mode 100644 index 118a9a9c..00000000 --- a/firmware/targets/f7/furi-hal/furi-hal-lpuart.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include <stddef.h> -#include <stdint.h> -#include "furi-hal-console.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -void furi_hal_lpuart_init(); - -void furi_hal_lpuart_deinit(); - -void furi_hal_lpuart_set_br(uint32_t baud); - -void furi_hal_lpuart_tx(const uint8_t* buffer, size_t buffer_size); - -void furi_hal_lpuart_set_irq_cb(void (*cb)(UartIrqEvent ev, uint8_t data)); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-uart.c b/firmware/targets/f7/furi-hal/furi-hal-uart.c new file mode 100644 index 00000000..c6e74101 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-uart.c @@ -0,0 +1,197 @@ +#include <furi-hal-uart.h> +#include <stdbool.h> +#include <stm32wbxx_ll_lpuart.h> +#include <stm32wbxx_ll_usart.h> +#include <furi-hal-resources.h> + +#include <furi.h> + +static void (*irq_cb[2])(uint8_t ev, uint8_t data); + +static void furi_hal_usart_init(uint32_t baud) { + hal_gpio_init_ex( + &gpio_usart_tx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + hal_gpio_init_ex( + &gpio_usart_rx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + + LL_USART_InitTypeDef USART_InitStruct = {0}; + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = baud; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); + LL_USART_EnableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + LL_USART_Enable(USART1); + + while(!LL_USART_IsActiveFlag_TEACK(USART1)); + + LL_USART_EnableIT_RXNE_RXFNE(USART1); + LL_USART_EnableIT_IDLE(USART1); + HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); +} + +static void furi_hal_lpuart_init(uint32_t baud) { + hal_gpio_init_ex( + &gpio_ext_pc0, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn8LPUART1); + hal_gpio_init_ex( + &gpio_ext_pc1, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn8LPUART1); + + LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; + LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct.BaudRate = 115200; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; + LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_EnableFIFO(LPUART1); + + LL_LPUART_Enable(LPUART1); + + while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))); + + furi_hal_uart_set_br(FuriHalUartIdLPUART1, baud); + + LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); + LL_LPUART_EnableIT_IDLE(LPUART1); + HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0); +} + +void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) { + if (ch == FuriHalUartIdLPUART1) + furi_hal_lpuart_init(baud); + else if (ch == FuriHalUartIdUSART1) + furi_hal_usart_init(baud); +} + +void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) { + if (ch == FuriHalUartIdUSART1) { + if (LL_USART_IsEnabled(USART1)) { + // Wait for transfer complete flag + while (!LL_USART_IsActiveFlag_TC(USART1)); + LL_USART_Disable(USART1); + uint32_t uartclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); + LL_USART_SetBaudRate(USART1, uartclk, LL_USART_PRESCALER_DIV1, LL_USART_OVERSAMPLING_16, baud); + LL_USART_Enable(USART1); + } + } else if (ch == FuriHalUartIdLPUART1) { + if (LL_LPUART_IsEnabled(LPUART1)) { + // Wait for transfer complete flag + while (!LL_LPUART_IsActiveFlag_TC(LPUART1)); + LL_LPUART_Disable(LPUART1); + uint32_t uartclk = LL_RCC_GetLPUARTClockFreq(LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1)); + if (uartclk/baud > 4095) { + LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV32); + LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV32, baud); + } else { + LL_LPUART_SetPrescaler(LPUART1, LL_LPUART_PRESCALER_DIV1); + LL_LPUART_SetBaudRate(LPUART1, uartclk, LL_LPUART_PRESCALER_DIV1, baud); + } + LL_LPUART_Enable(LPUART1); + } + } +} + +void furi_hal_uart_deinit(FuriHalUartId ch) { + furi_hal_uart_set_irq_cb(ch, NULL); + if (ch == FuriHalUartIdUSART1) { + LL_USART_Disable(USART1); + hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (ch == FuriHalUartIdLPUART1) { + LL_LPUART_Disable(LPUART1); + hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } +} + +void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size) { + if (ch == FuriHalUartIdUSART1) { + if (LL_USART_IsEnabled(USART1) == 0) + return; + + while(buffer_size > 0) { + while (!LL_USART_IsActiveFlag_TXE(USART1)); + + LL_USART_TransmitData8(USART1, *buffer); + buffer++; + buffer_size--; + } + + } else if (ch == FuriHalUartIdLPUART1) { + if (LL_LPUART_IsEnabled(LPUART1) == 0) + return; + + while(buffer_size > 0) { + while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)); + + LL_LPUART_TransmitData8(LPUART1, *buffer); + + buffer++; + buffer_size--; + } + } +} + +void furi_hal_uart_set_irq_cb(FuriHalUartId ch, void (*cb)(UartIrqEvent ev, uint8_t data)) { + if (cb == NULL) { + if (ch == FuriHalUartIdUSART1) + NVIC_DisableIRQ(USART1_IRQn); + else if (ch == FuriHalUartIdLPUART1) + NVIC_DisableIRQ(LPUART1_IRQn); + irq_cb[ch] = cb; + } else { + irq_cb[ch] = cb; + if (ch == FuriHalUartIdUSART1) + NVIC_EnableIRQ(USART1_IRQn); + else if (ch == FuriHalUartIdLPUART1) + NVIC_EnableIRQ(LPUART1_IRQn); + } +} + +void LPUART1_IRQHandler(void) { + if (LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) { + uint8_t data = LL_LPUART_ReceiveData8(LPUART1); + irq_cb[FuriHalUartIdLPUART1](UartIrqEventRXNE, data); + } else if (LL_LPUART_IsActiveFlag_IDLE(LPUART1)) { + irq_cb[FuriHalUartIdLPUART1](UartIrqEventIDLE, 0); + LL_LPUART_ClearFlag_IDLE(LPUART1); + } + //TODO: more events +} + +void USART1_IRQHandler(void) { + if (LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) { + uint8_t data = LL_USART_ReceiveData8(USART1); + irq_cb[FuriHalUartIdUSART1](UartIrqEventRXNE, data); + } else if (LL_USART_IsActiveFlag_IDLE(USART1)) { + irq_cb[FuriHalUartIdUSART1](UartIrqEventIDLE, 0); + LL_USART_ClearFlag_IDLE(USART1); + } +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-uart.h b/firmware/targets/f7/furi-hal/furi-hal-uart.h new file mode 100644 index 00000000..6be156b7 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-uart.h @@ -0,0 +1,29 @@ +#pragma once + +#include <stddef.h> +#include <stdint.h> +#include "furi-hal-console.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FuriHalUartIdUSART1, + FuriHalUartIdLPUART1, +} FuriHalUartId; + + +void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud); + +void furi_hal_uart_deinit(FuriHalUartId ch); + +void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud); + +void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size); + +void furi_hal_uart_set_irq_cb(FuriHalUartId ch, void (*cb)(UartIrqEvent ev, uint8_t data)); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c index e643fe57..9386b100 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c +++ b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c @@ -7,12 +7,12 @@ #include "usb_cdc.h" #define CDC0_RXD_EP 0x01 -#define CDC0_TXD_EP 0x82 -#define CDC0_NTF_EP 0x83 +#define CDC0_TXD_EP 0x81 +#define CDC0_NTF_EP 0x82 -#define CDC1_RXD_EP 0x04 -#define CDC1_TXD_EP 0x85 -#define CDC1_NTF_EP 0x86 +#define CDC1_RXD_EP 0x03 +#define CDC1_TXD_EP 0x83 +#define CDC1_NTF_EP 0x84 #define CDC_NTF_SZ 0x08 diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index 4ac95d82..eb1fefeb 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -36,7 +36,7 @@ template <unsigned int N> struct STOP_EXTERNING_ME {}; #include "furi-hal-usb.h" #include "furi-hal-usb-hid.h" #include "furi-hal-compress.h" -#include "furi-hal-lpuart.h" +#include "furi-hal-uart.h" /** Init furi-hal */ void furi_hal_init(); |