6c74ea65c2
* Add saving to SD-Card (not ready yet) * Add saving to SD-card (done) * Select previous menu item * Fix central button * Fix current_button * Refactoring * Add notifications * [FL-1417] Add IRDA CLI CLI commands: 1) ir_rx Receives all IR-trafic, decodes and prints result to stdout 2) ir_tx <protocol> <address> <command> Transmits IR-signal. Address and command are hex-formatted * Fix BUG with random memory corruption at random time in random place in random universe in random unknown space and time forever amen * Fix submenu set_selected_item * Bring protocol order back * Add TODO sdcard check
105 lines
3.2 KiB
C++
105 lines
3.2 KiB
C++
#include "app-template.h"
|
|
#include "cli/cli.h"
|
|
#include "cmsis_os2.h"
|
|
#include <furi.h>
|
|
#include <api-hal-irda.h>
|
|
#include "irda.h"
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <m-string.h>
|
|
|
|
typedef struct IrdaCli {
|
|
IrdaHandler* handler;
|
|
osMessageQueueId_t message_queue;
|
|
} IrdaCli;
|
|
|
|
static void irda_rx_callback(void* ctx, bool level, uint32_t duration) {
|
|
IrdaCli* irda_cli = (IrdaCli*)ctx;
|
|
const IrdaMessage* message;
|
|
message = irda_decode(irda_cli->handler, level, duration);
|
|
if(message) {
|
|
osMessageQueuePut(irda_cli->message_queue, message, 0, 0);
|
|
}
|
|
}
|
|
|
|
static void irda_cli_start_ir_rx(Cli* cli, string_t args, void* context) {
|
|
if(api_hal_irda_rx_irq_is_busy()) {
|
|
printf("IRDA is busy. Exit.");
|
|
return;
|
|
}
|
|
IrdaCli irda_cli;
|
|
irda_cli.handler = irda_alloc_decoder();
|
|
irda_cli.message_queue = osMessageQueueNew(2, sizeof(IrdaMessage), NULL);
|
|
api_hal_irda_rx_irq_init();
|
|
api_hal_irda_rx_irq_set_callback(irda_rx_callback, &irda_cli);
|
|
|
|
printf("Receiving IRDA...\r\nPress Ctrl+C to abort\r\n");
|
|
while(!cli_cmd_interrupt_received(cli)) {
|
|
IrdaMessage message;
|
|
if(osOK == osMessageQueueGet(irda_cli.message_queue, &message, NULL, 50)) {
|
|
printf(
|
|
"%s, A:0x%0*lX, C:0x%0*lX%s\r\n",
|
|
irda_get_protocol_name(message.protocol),
|
|
irda_get_protocol_address_length(message.protocol),
|
|
message.address,
|
|
irda_get_protocol_command_length(message.protocol),
|
|
message.command,
|
|
message.repeat ? " R" : "");
|
|
}
|
|
}
|
|
|
|
api_hal_irda_rx_irq_deinit();
|
|
irda_free_decoder(irda_cli.handler);
|
|
osMessageQueueDelete(irda_cli.message_queue);
|
|
}
|
|
|
|
static void irda_cli_print_usage(void) {
|
|
printf("Usage:\r\n\tir_tx <protocol> <command> <address>\r\n");
|
|
printf("\t<command> and <address> are hex-formatted\r\n");
|
|
printf("\tAvailable protocols:");
|
|
for(int i = 0; irda_is_protocol_valid((IrdaProtocol)i); ++i) {
|
|
printf(" %s", irda_get_protocol_name((IrdaProtocol)i));
|
|
}
|
|
printf("\r\n");
|
|
}
|
|
|
|
static void irda_cli_start_ir_tx(Cli* cli, string_t args, void* context) {
|
|
if(api_hal_irda_rx_irq_is_busy()) {
|
|
printf("IRDA is busy. Exit.");
|
|
return;
|
|
}
|
|
auto ss = std::istringstream(string_get_cstr(args));
|
|
uint32_t command = 0;
|
|
uint32_t address = 0;
|
|
std::string protocol_name;
|
|
|
|
if(!(ss >> protocol_name) || !(ss >> std::hex >> address) || !(ss >> std::hex >> command)) {
|
|
printf("Wrong arguments.\r\n");
|
|
irda_cli_print_usage();
|
|
return;
|
|
}
|
|
|
|
IrdaProtocol protocol = irda_get_protocol_by_name(protocol_name.c_str());
|
|
|
|
if(!irda_is_protocol_valid(protocol)) {
|
|
printf("Unknown protocol.\r\n");
|
|
irda_cli_print_usage();
|
|
return;
|
|
}
|
|
|
|
IrdaMessage message = {
|
|
.protocol = protocol,
|
|
.address = address,
|
|
.command = command,
|
|
.repeat = false,
|
|
};
|
|
irda_send(&message, 1);
|
|
}
|
|
|
|
extern "C" void irda_cli_init() {
|
|
Cli* cli = (Cli*)furi_record_open("cli");
|
|
cli_add_command(cli, "ir_rx", irda_cli_start_ir_rx, NULL);
|
|
cli_add_command(cli, "ir_tx", irda_cli_start_ir_tx, NULL);
|
|
furi_record_close("cli");
|
|
}
|