Skip to content

Commit

Permalink
Hex mode & bug fixes
Browse files Browse the repository at this point in the history
- Hex mode added (both for receiving and sending data)
- UART pins selection added (from 13 & 14 or 15 & 16 pins)
- UART settings are placed in a separate submenu
- Input from uart to help window fixed
  • Loading branch information
ElectronicsInFocus committed Nov 30, 2023
1 parent 0916cc1 commit c365e77
Show file tree
Hide file tree
Showing 16 changed files with 1,095 additions and 246 deletions.
32 changes: 23 additions & 9 deletions base_pack/uart_terminal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@
| [![FAP Factory](https://flipc.org/api/v1/cool4uma/UART_Terminal/badge)](https://flipc.org/cool4uma/UART_Terminal) | [![FAP Factory](https://flipc.org/api/v1/cool4uma/UART_Terminal/badge?firmware=unleashed)](https://flipc.org/cool4uma/UART_Terminal?firmware=unleashed) |

## Capabilities
- Read log and command output by uart
- Send commands by uart
- Set baud rate
- Fast commands
- Reading from UART in text or hex mode
- Sending commands
- Sending AT commands
- Sending fast commands
- Sending binary packets (in hex)
- Baudrate selection
- UART pins selection (2 options)

## Connecting
| Flipper Zero pin | UART interface |
| ---------------- | --------------- |
| 13 TX | RX |
| 14 RX | TX |
|8, 18 GND | GND |
| Device UART interface | Flipper Zero pin (default) | Flipper Zero pin (option) |
| :----------------: | :---------------: | :---------------: |
| RX | 13 TX | 15 TX |
| TX | 14 RX | 16 TX |
| GND | 8, 18 GND | 8, 18 GND |

Info: If possible, do not power your devices from 3V3 (pin 9) Flipper Zero. It does not support hot plugging.

Expand All @@ -27,6 +30,17 @@ To accommodate more characters on a small display, some characters are called up

![kbf](https://user-images.githubusercontent.com/122148894/212286637-7063f1ee-c6ff-46b9-8dc5-79a5f367fab1.png)

## Supported send AT commands
In the "Send AT command" mode, the keyboard settings are changed for the convenience of entering AT commands.

![AT](https://user-images.githubusercontent.com/122148894/230785072-319fe5c9-deca-49f9-bfe4-5ace89d38d53.png)

## Hex mode
Hexadecimal mode is useful for working with simple binary protocols.
You can see the bytes being received in hexadecimal in the terminal window.
You can also send binary packets to UART. A simplified keyboard is used to enter packet bytes.

![004](https://github.com/rnadyrshin/UART_Terminal/assets/110516632/d5d3c09b-accc-4e6f-b777-81e751284108)

## How to install
Copy the contents of the repository to the applications_user/uart_terminal folder Flipper Zero firmware and build app with the command ./fbt fap_uart_terminal.
Expand Down
2 changes: 1 addition & 1 deletion base_pack/uart_terminal/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ App(
fap_category="GPIO",
fap_icon_assets="assets",
fap_author="@cool4uma & (some fixes by @xMasterX)",
fap_version="1.2",
fap_version="1.3",
fap_description="Control various devices via the Flipper Zero UART interface.",
)
6 changes: 6 additions & 0 deletions base_pack/uart_terminal/scenes/uart_terminal_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ extern const SceneManagerHandlers uart_terminal_scene_handlers;
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "uart_terminal_scene_config.h"
#undef ADD_SCENE

#define UART_PINS_ITEM_IDX (0)
#define BAUDRATE_ITEM_IDX (1)
#define HEX_MODE_ITEM_IDX (2)

#define DEFAULT_BAUDRATE_OPT_IDX (18)
3 changes: 3 additions & 0 deletions base_pack/uart_terminal/scenes/uart_terminal_scene_config.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
ADD_SCENE(uart_terminal, start, Start)
ADD_SCENE(uart_terminal, setup, Setup)
ADD_SCENE(uart_terminal, console_output, ConsoleOutput)
ADD_SCENE(uart_terminal, text_input, UART_TextInput)
ADD_SCENE(uart_terminal, hex_input, UART_HexInput)
ADD_SCENE(uart_terminal, help, Help)
233 changes: 79 additions & 154 deletions base_pack/uart_terminal/scenes/uart_terminal_scene_console_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,177 +3,77 @@
void uart_terminal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
furi_assert(context);
UART_TerminalApp* app = context;
FuriString* new_str = furi_string_alloc();

if(app->hex_mode) {
while (len--) {
uint8_t byte = *(buf++);
if(byte == '\0') break;
furi_string_cat_printf(new_str, "%02X ", byte);
}
}
else {
buf[len] = '\0';
furi_string_cat_printf(new_str, "%s", buf);
}

// If text box store gets too big, then truncate it
app->text_box_store_strlen += len;
if(app->text_box_store_strlen >= UART_TERMINAL_TEXT_BOX_STORE_SIZE - 1) {
app->text_box_store_strlen += furi_string_size(new_str);;
while(app->text_box_store_strlen >= UART_TERMINAL_TEXT_BOX_STORE_SIZE - 1) {
furi_string_right(app->text_box_store, app->text_box_store_strlen / 2);
app->text_box_store_strlen = furi_string_size(app->text_box_store) + len;
}

// Null-terminate buf and append to text box store
buf[len] = '\0';
furi_string_cat_printf(app->text_box_store, "%s", buf);
furi_string_cat(app->text_box_store, new_str);
furi_string_free(new_str);

view_dispatcher_send_custom_event(
app->view_dispatcher, UART_TerminalEventRefreshConsoleOutput);
}

static uint8_t hex_char_to_byte(const char c) {
if(c >= '0' && c <= '9') {
return c-'0';
}
if(c >= 'A' && c <= 'F') {
return c-'A'+10;
}
if (c >= 'a' && c <= 'f') {
return c-'a'+10;
}
return 0;
}

void uart_terminal_scene_console_output_on_enter(void* context) {
UART_TerminalApp* app = context;

TextBox* text_box = app->text_box;
text_box_reset(app->text_box);
text_box_set_font(text_box, TextBoxFontText);
if(app->focus_console_start) {
text_box_set_focus(text_box, TextBoxFocusStart);
} else {
text_box_set_focus(text_box, TextBoxFocusEnd);
}
text_box_set_focus(text_box, TextBoxFocusEnd);

//Change baudrate ///////////////////////////////////////////////////////////////////////////
if(0 == strncmp("75", app->selected_tx_string, strlen("75")) && app->BAUDRATE != 75) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 75;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("110", app->selected_tx_string, strlen("110")) && app->BAUDRATE != 110) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 110;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("150", app->selected_tx_string, strlen("150")) && app->BAUDRATE != 150) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 150;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("300", app->selected_tx_string, strlen("300")) && app->BAUDRATE != 300) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 300;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("600", app->selected_tx_string, strlen("600")) && app->BAUDRATE != 600) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 600;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("1200", app->selected_tx_string, strlen("1200")) && app->BAUDRATE != 1200) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 1200;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("1800", app->selected_tx_string, strlen("1800")) && app->BAUDRATE != 1800) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 1800;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("2400", app->selected_tx_string, strlen("2400")) && app->BAUDRATE != 2400) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 2400;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("4800", app->selected_tx_string, strlen("4800")) && app->BAUDRATE != 4800) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 4800;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("7200", app->selected_tx_string, strlen("7200")) && app->BAUDRATE != 7200) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 7200;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("9600", app->selected_tx_string, strlen("9600")) && app->BAUDRATE != 9600) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 9600;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("14400", app->selected_tx_string, strlen("14400")) && app->BAUDRATE != 14400) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 14400;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("19200", app->selected_tx_string, strlen("19200")) && app->BAUDRATE != 19200) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 19200;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("38400", app->selected_tx_string, strlen("38400")) && app->BAUDRATE != 38400) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 38400;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("56000", app->selected_tx_string, strlen("56000")) && app->BAUDRATE != 56000) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 56000;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("57600", app->selected_tx_string, strlen("57600")) && app->BAUDRATE != 57600) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 57600;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("76800", app->selected_tx_string, strlen("76800")) && app->BAUDRATE != 76800) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 76800;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("115200", app->selected_tx_string, strlen("115200")) &&
app->BAUDRATE != 115200) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 115200;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("128000", app->selected_tx_string, strlen("128000")) && app->BAUDRATE != 128000) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 128000;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("230400", app->selected_tx_string, strlen("230400")) &&
app->BAUDRATE != 230400) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 230400;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("250000", app->selected_tx_string, strlen("250000")) && app->BAUDRATE != 250000) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 250000;
app->uart = uart_terminal_uart_init(app);
}
if(0 == strncmp("256000", app->selected_tx_string, strlen("256000")) && app->BAUDRATE != 256000) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 256000;
app->uart = uart_terminal_uart_init(app);
bool need_reinit = false;

//Change baudrate
if(app->BAUDRATE != app->NEW_BAUDRATE && app->NEW_BAUDRATE) {
need_reinit = true;
}
if(0 == strncmp("460800", app->selected_tx_string, strlen("460800")) &&
app->BAUDRATE != 460800) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 460800;
app->uart = uart_terminal_uart_init(app);

//Change UART port
if(app->uart_ch != app->new_uart_ch) {
need_reinit = true;
}
if(0 == strncmp("921600", app->selected_tx_string, strlen("921600")) &&
app->BAUDRATE != 921600) {

if(need_reinit) {
uart_terminal_uart_free(app->uart);
app->BAUDRATE = 921600;
app->BAUDRATE = app->NEW_BAUDRATE;
app->uart_ch = app->new_uart_ch;
app->uart = uart_terminal_uart_init(app);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////

if(app->is_command) {
furi_string_reset(app->text_box_store);
app->text_box_store_strlen = 0;

if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
const char* help_msg =
"UART terminal for Flipper\n\nI'm in github: cool4uma\n\nThis app is a modified\nWiFi Marauder companion,\nThanks 0xchocolate(github)\nfor great code and app.\n\n";
furi_string_cat_str(app->text_box_store, help_msg);
app->text_box_store_strlen += strlen(help_msg);
}

if(app->show_stopscan_tip) {
const char* help_msg = "Press BACK to return\n";
furi_string_cat_str(app->text_box_store, help_msg);
app->text_box_store_strlen += strlen(help_msg);
}
}

// Set starting text - for "View Log", this will just be what was already in the text box store
Expand All @@ -186,16 +86,41 @@ void uart_terminal_scene_console_output_on_enter(void* context) {
uart_terminal_uart_set_handle_rx_data_cb(
app->uart, uart_terminal_console_output_handle_rx_data_cb); // setup callback for rx thread

// Send command with CR+LF or newline '\n'
if(app->is_command && app->selected_tx_string) {
if(app->TERMINAL_MODE == 1){
uart_terminal_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
uart_terminal_uart_tx((uint8_t*)("\r\n"), 2);
} else {
uart_terminal_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
uart_terminal_uart_tx((uint8_t*)("\n"), 1);
uint8_t uart_ch = app->uart_ch;

if(app->hex_mode) {
// Send binary packet
if(app->selected_tx_string) {
const char *str = app->selected_tx_string;
uint8_t digit_num = 0;
uint8_t byte = 0;
while (*str) {
byte |= (hex_char_to_byte(*str) << ((1 - digit_num) * 4));

if(++digit_num == 2) {
uart_terminal_uart_tx(uart_ch, &byte, 1);
digit_num = 0;
byte = 0;
}
str++;
}

if(digit_num) {
uart_terminal_uart_tx(uart_ch, &byte, 1);
}
}
} else {
// Send command with CR+LF or newline '\n'
if(app->is_command && app->selected_tx_string) {
if(app->TERMINAL_MODE == 1){
uart_terminal_uart_tx(uart_ch,
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
uart_terminal_uart_tx(uart_ch, (uint8_t*)("\r\n"), 2);
} else {
uart_terminal_uart_tx(uart_ch,
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
uart_terminal_uart_tx(uart_ch, (uint8_t*)("\n"), 1);
}
}
}
}
Expand Down
Loading

0 comments on commit c365e77

Please sign in to comment.