From 239c174610c4852b35f57d0e60bc440b5bdb0642 Mon Sep 17 00:00:00 2001 From: gornekich <44112859+gornekich@users.noreply.github.com> Date: Mon, 19 Apr 2021 19:36:45 +0300 Subject: [FL-1062] Add cli commands for IrDA (#409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * irda: add ir_tx command * api-hal-vcp: add receive with timeout * cli: add command termination check function * irda: add cli_rx command * cli: reduce timeout for Ctrl+C command check * irda: fix ir_rx command * irda: add ir_tx cli command hints Co-authored-by: あく --- applications/irda/irda.c | 122 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 5 deletions(-) mode change 100644 => 100755 applications/irda/irda.c (limited to 'applications/irda') diff --git a/applications/irda/irda.c b/applications/irda/irda.c old mode 100644 new mode 100755 index 2eb8bd97..6944f276 --- a/applications/irda/irda.c +++ b/applications/irda/irda.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "irda_nec.h" #include "irda_samsung.h" @@ -35,6 +36,12 @@ typedef struct { #define IRDA_PACKET_COUNT 8 +typedef struct { + osMessageQueueId_t cli_ir_rx_queue; + Cli* cli; + bool cli_cmd_is_active; +} IrDAApp; + typedef struct { uint8_t mode_id; uint16_t carrier_freq; @@ -235,6 +242,93 @@ void init_packet( state->packets[index].command = command; } +void irda_cli_cmd_rx(string_t args, void* context) { + furi_assert(context); + IrDAPacket packet; + IrDAApp* app = context; + app->cli_cmd_is_active = true; + bool exit = false; + + printf("Reading income packets...\r\nPress Ctrl+C to abort\r\n"); + while(!exit) { + exit = cli_cmd_interrupt_received(app->cli); + osStatus status = osMessageQueueGet(app->cli_ir_rx_queue, &packet, 0, 50); + if(status == osOK) { + if(packet.protocol == IRDA_NEC) { + printf("NEC "); + } else if(packet.protocol == IRDA_SAMSUNG) { + printf("SAMSUNG "); + } + printf( + "Address:0x%02X%02X Command: 0x%02X\r\n", + (uint8_t)(packet.address >> 8), + (uint8_t)packet.address, + (uint8_t)packet.command); + } + } + printf("Interrupt command received"); + app->cli_cmd_is_active = false; + return; +} + +void irda_cli_cmd_tx(string_t args, void* context) { + furi_assert(context); + ValueMutex* state_mutex = context; + // Read protocol name + IrDAProtocolType protocol; + string_t protocol_str; + string_init(protocol_str); + size_t ws = string_search_char(args, ' '); + if(ws == STRING_FAILURE) { + printf("Invalid input. Use ir_tx PROTOCOL ADDRESS COMMAND"); + string_clear(protocol_str); + return; + } else { + string_set_n(protocol_str, args, 0, ws); + string_right(args, ws); + string_strim(args); + } + if(!string_cmp_str(protocol_str, "NEC")) { + protocol = IRDA_NEC; + } else if(!string_cmp_str(protocol_str, "SAMSUNG")) { + protocol = IRDA_SAMSUNG; + } else { + printf("Incorrect protocol. Valid protocols: `NEC`, `SAMSUNG`"); + string_clear(protocol_str); + return; + } + string_clear(protocol_str); + // Read address + uint16_t address = strtoul(string_get_cstr(args), NULL, 16); + ws = string_search_char(args, ' '); + if(!(ws == 4 || ws == 6)) { + printf("Invalid address format. Use 4 [0-F] hex digits in 0xXXXX or XXXX formats"); + return; + } + string_right(args, ws); + string_strim(args); + // Read command + uint16_t command = strtoul(string_get_cstr(args), NULL, 16); + ws = string_search_char(args, '\0'); + if(!(ws == 4 || ws == 6)) { + printf("Invalid command format. Use 4 [0-F] hex digits in 0xXXXX or XXXX formats"); + return; + } + + State* state = (State*)acquire_mutex(state_mutex, 25); + if(state == NULL) { + printf("IRDA resources busy\r\n"); + return; + } + if(protocol == IRDA_NEC) { + ir_nec_send(address, command); + } else if(protocol == IRDA_SAMSUNG) { + ir_samsung_send(address, command); + } + release_mutex(state_mutex, state); + return; +} + int32_t irda(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(AppEvent), NULL); @@ -247,6 +341,11 @@ int32_t irda(void* p) { _state.mode_id = 0; _state.packet_id = 0; + IrDAApp irda_app; + irda_app.cli = furi_record_open("cli"); + irda_app.cli_ir_rx_queue = osMessageQueueNew(1, sizeof(IrDAPacket), NULL); + irda_app.cli_cmd_is_active = false; + for(uint8_t i = 0; i < IRDA_PACKET_COUNT; i++) { init_packet(&_state, i, IRDA_UNKNOWN, 0, 0); } @@ -271,6 +370,9 @@ int32_t irda(void* p) { view_port_draw_callback_set(view_port, render_callback, &state_mutex); view_port_input_callback_set(view_port, input_callback, event_queue); + cli_add_command(irda_app.cli, "ir_rx", irda_cli_cmd_rx, &irda_app); + cli_add_command(irda_app.cli, "ir_tx", irda_cli_cmd_tx, &state_mutex); + // Open GUI and register view_port Gui* gui = furi_record_open("gui"); gui_add_view_port(gui, view_port, GuiLayerFullscreen); @@ -306,6 +408,10 @@ int32_t irda(void* p) { delete_mutex(&state_mutex); osMessageQueueDelete(event_queue); + osMessageQueueDelete(irda_app.cli_ir_rx_queue); + cli_delete_command(irda_app.cli, "ir_rx"); + cli_delete_command(irda_app.cli, "ir_tx"); + furi_record_close("cli"); // exit return 0; @@ -346,6 +452,10 @@ int32_t irda(void* p) { if(decoded) { // save only if we in packet mode State* state = (State*)acquire_mutex_block(&state_mutex); + IrDAPacket packet; + packet.protocol = IRDA_NEC; + packet.address = out_data[1] << 8 | out_data[0]; + packet.command = out_data[2]; if(state->mode_id == 1) { if(out.protocol == IRDA_NEC) { @@ -356,15 +466,17 @@ int32_t irda(void* p) { printf("R"); } printf("\r\n"); - - state->packets[state->packet_id].protocol = IRDA_NEC; - state->packets[state->packet_id].address = out_data[1] << 8 | - out_data[0]; - state->packets[state->packet_id].command = out_data[2]; + // Save packet to state + memcpy( + &(state->packets[state->packet_id]), &packet, sizeof(IrDAPacket)); } else { printf("Unknown protocol\r\n"); } } + if(irda_app.cli_cmd_is_active) { + // Send decoded packet to cli + osMessageQueuePut(irda_app.cli_ir_rx_queue, &packet, 0, 0); + } release_mutex(&state_mutex, state); view_port_update(view_port); -- cgit v1.2.3