Merge branch 'dev' into reborned/nfc_ui_refactor_2

This commit is contained in:
あく
2024-01-16 18:19:27 +09:00
committed by GitHub
63 changed files with 4334 additions and 835 deletions

View File

@@ -3,7 +3,7 @@ App(
name="GPIO",
apptype=FlipperAppType.MENUEXTERNAL,
entry_point="gpio_app",
stack_size=1 * 1024,
stack_size=2 * 1024,
icon="A_GPIO_14",
order=50,
fap_libs=["assets"],

View File

@@ -46,7 +46,7 @@ void line_ensure_flow_invariant(GpioApp* app) {
// selected. This function enforces that invariant by resetting flow_pins
// to None if it is configured to 16,15 when LPUART is selected.
uint8_t available_flow_pins = app->usb_uart_cfg->uart_ch == FuriHalUartIdLPUART1 ? 3 : 4;
uint8_t available_flow_pins = app->usb_uart_cfg->uart_ch == FuriHalSerialIdLpuart ? 3 : 4;
VariableItem* item = app->var_item_flow;
variable_item_set_values_count(item, available_flow_pins);
@@ -77,9 +77,9 @@ static void line_port_cb(VariableItem* item) {
variable_item_set_current_value_text(item, uart_ch[index]);
if(index == 0)
app->usb_uart_cfg->uart_ch = FuriHalUartIdUSART1;
app->usb_uart_cfg->uart_ch = FuriHalSerialIdUsart;
else if(index == 1)
app->usb_uart_cfg->uart_ch = FuriHalUartIdLPUART1;
app->usb_uart_cfg->uart_ch = FuriHalSerialIdLpuart;
line_ensure_flow_invariant(app);
view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet);

View File

@@ -29,17 +29,18 @@ typedef enum {
WorkerEvtTxStop = (1 << 2),
WorkerEvtCdcRx = (1 << 3),
WorkerEvtCdcTxComplete = (1 << 4),
WorkerEvtCfgChange = (1 << 4),
WorkerEvtCfgChange = (1 << 5),
WorkerEvtLineCfgSet = (1 << 5),
WorkerEvtCtrlLineSet = (1 << 6),
WorkerEvtLineCfgSet = (1 << 6),
WorkerEvtCtrlLineSet = (1 << 7),
} WorkerEvtFlags;
#define WORKER_ALL_RX_EVENTS \
(WorkerEvtStop | WorkerEvtRxDone | WorkerEvtCfgChange | WorkerEvtLineCfgSet | \
WorkerEvtCtrlLineSet)
WorkerEvtCtrlLineSet | WorkerEvtCdcTxComplete)
#define WORKER_ALL_TX_EVENTS (WorkerEvtTxStop | WorkerEvtCdcRx)
struct UsbUartBridge {
@@ -50,6 +51,7 @@ struct UsbUartBridge {
FuriThread* tx_thread;
FuriStreamBuffer* rx_stream;
FuriHalSerialHandle* serial_handle;
FuriMutex* usb_mutex;
@@ -80,11 +82,23 @@ static const CdcCallbacks cdc_cb = {
static int32_t usb_uart_tx_thread(void* context);
static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
static void usb_uart_on_irq_rx_dma_cb(
FuriHalSerialHandle* handle,
FuriHalSerialRxEvent ev,
size_t size,
void* context) {
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
if(ev == UartIrqEventRXNE) {
furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0);
if(ev & (FuriHalSerialRxEventData | FuriHalSerialRxEventIdle)) {
uint8_t data[FURI_HAL_SERIAL_DMA_BUFFER_SIZE] = {0};
while(size) {
size_t ret = furi_hal_serial_dma_rx(
handle,
data,
(size > FURI_HAL_SERIAL_DMA_BUFFER_SIZE) ? FURI_HAL_SERIAL_DMA_BUFFER_SIZE : size);
furi_stream_buffer_send(usb_uart->rx_stream, data, ret, 0);
size -= ret;
};
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone);
}
}
@@ -116,32 +130,33 @@ static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
}
static void usb_uart_serial_init(UsbUartBridge* usb_uart, uint8_t uart_ch) {
if(uart_ch == FuriHalUartIdUSART1) {
furi_hal_console_disable();
} else if(uart_ch == FuriHalUartIdLPUART1) {
furi_hal_uart_init(uart_ch, 115200);
}
furi_hal_uart_set_irq_cb(uart_ch, usb_uart_on_irq_cb, usb_uart);
furi_assert(!usb_uart->serial_handle);
usb_uart->serial_handle = furi_hal_serial_control_acquire(uart_ch);
furi_assert(usb_uart->serial_handle);
furi_hal_serial_init(usb_uart->serial_handle, 115200);
furi_hal_serial_dma_rx_start(
usb_uart->serial_handle, usb_uart_on_irq_rx_dma_cb, usb_uart, false);
}
static void usb_uart_serial_deinit(UsbUartBridge* usb_uart, uint8_t uart_ch) {
UNUSED(usb_uart);
furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL);
if(uart_ch == FuriHalUartIdUSART1)
furi_hal_console_enable();
else if(uart_ch == FuriHalUartIdLPUART1)
furi_hal_uart_deinit(uart_ch);
static void usb_uart_serial_deinit(UsbUartBridge* usb_uart) {
furi_assert(usb_uart->serial_handle);
furi_hal_serial_deinit(usb_uart->serial_handle);
furi_hal_serial_control_release(usb_uart->serial_handle);
usb_uart->serial_handle = NULL;
}
static void usb_uart_set_baudrate(UsbUartBridge* usb_uart, uint32_t baudrate) {
if(baudrate != 0) {
furi_hal_uart_set_br(usb_uart->cfg.uart_ch, baudrate);
furi_hal_serial_set_br(usb_uart->serial_handle, baudrate);
usb_uart->st.baudrate_cur = baudrate;
} else {
struct usb_cdc_line_coding* line_cfg =
furi_hal_cdc_get_port_settings(usb_uart->cfg.vcp_ch);
if(line_cfg->dwDTERate > 0) {
furi_hal_uart_set_br(usb_uart->cfg.uart_ch, line_cfg->dwDTERate);
furi_hal_serial_set_br(usb_uart->serial_handle, line_cfg->dwDTERate);
usb_uart->st.baudrate_cur = line_cfg->dwDTERate;
}
}
@@ -191,7 +206,7 @@ static int32_t usb_uart_worker(void* context) {
furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
furi_check(!(events & FuriFlagError));
if(events & WorkerEvtStop) break;
if(events & WorkerEvtRxDone) {
if(events & (WorkerEvtRxDone | WorkerEvtCdcTxComplete)) {
size_t len = furi_stream_buffer_receive(
usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0);
if(len > 0) {
@@ -223,7 +238,7 @@ static int32_t usb_uart_worker(void* context) {
furi_thread_flags_set(furi_thread_get_id(usb_uart->tx_thread), WorkerEvtTxStop);
furi_thread_join(usb_uart->tx_thread);
usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch);
usb_uart_serial_deinit(usb_uart);
usb_uart_serial_init(usb_uart, usb_uart->cfg_new.uart_ch);
usb_uart->cfg.uart_ch = usb_uart->cfg_new.uart_ch;
@@ -274,7 +289,7 @@ static int32_t usb_uart_worker(void* context) {
}
}
usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch);
usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch);
usb_uart_serial_deinit(usb_uart);
furi_hal_gpio_init(USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
@@ -320,18 +335,10 @@ static int32_t usb_uart_tx_thread(void* context) {
if(usb_uart->cfg.software_de_re != 0)
furi_hal_gpio_write(USB_USART_DE_RE_PIN, false);
furi_hal_uart_tx(usb_uart->cfg.uart_ch, data, len);
furi_hal_serial_tx(usb_uart->serial_handle, data, len);
if(usb_uart->cfg.software_de_re != 0) {
//TODO: FL-3276 port to new USART API
if(usb_uart->cfg.uart_ch == FuriHalUartIdUSART1) {
while(!LL_USART_IsActiveFlag_TC(USART1))
;
} else if(usb_uart->cfg.uart_ch == FuriHalUartIdLPUART1) {
while(!LL_LPUART_IsActiveFlag_TC(LPUART1))
;
}
furi_hal_serial_tx_wait_complete(usb_uart->serial_handle);
furi_hal_gpio_write(USB_USART_DE_RE_PIN, true);
}
}
@@ -345,6 +352,7 @@ static int32_t usb_uart_tx_thread(void* context) {
static void vcp_on_cdc_tx_complete(void* context) {
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
furi_semaphore_release(usb_uart->tx_sem);
furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtCdcTxComplete);
}
static void vcp_on_cdc_rx(void* context) {

View File

@@ -8,8 +8,6 @@
#include <furi_hal_usb_hid_u2f.h>
#include <storage/storage.h>
#include <furi_hal_console.h>
#define TAG "U2fHid"
#define WORKER_TAG TAG "Worker"