Skip to content

Commit

Permalink
Project layout refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
IDV7 committed May 23, 2024
1 parent 0599312 commit 8fbbf38
Show file tree
Hide file tree
Showing 34 changed files with 3,979 additions and 0 deletions.
165 changes: 165 additions & 0 deletions software/MySrc/Common/cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
This file is part of the CLI module.
It contains the functionallity to handle the CLI commands.
You should NOT ADD COMMANDS HERE. Use cli_cmd_callbacks.c instead.
*/

#include "cli.h"

#include <stdint.h>

#include "usbd_cdc_if.h"

#include "log.h"
#include "version.h"
#include "misc.h"
#include "cli_cmd_callbacks.h"
#include "main.h"

void cli_handle_cmd(cli_handle_t *cli_h);

void cli_process(void *arg) {
if (arg == NULL) {
LOGE("cli_process: arg is NULL! Not processing cli... unsafe!");
return;
}
cli_handle_t *cli_h = (cli_handle_t *)arg;

// read data
if (cli_h->new_data_flag) { // if new data data in buffer
cli_h->new_data_flag = false;
LOG("-> %s", cli_h->cli_rx_buffer);
cli_handle_cmd(cli_h);
}

//write data (from buffer)
}

void cli_init(cli_handle_t *cli_h) {
LOGD("CLI Init...");

cli_h->cli_connected_flag = false;

uint8_t version_string[10];
VERSION_TO_STRING(CLI_VERSION, version_string);
LOGD("CLI is on version %s", version_string);

//init the cmd_list array to NULL
for (size_t i = 0; i < MAX_CMD_COUNT; i++) {
cli_h->cmd_list[i].cmd_str = NULL;
}

cli_h->new_data_flag = false;

add_commands(cli_h);

//wait for connection
if (cli_h->cli_connected_flag == false && cli_h->halt_until_connected_flag == true) {
LOGD("Waiting for connection...");
while (cli_h->cli_connected_flag == false) {
LED_toggle();
delay(100);
if (cli_h->new_data_flag == true) {
cli_h->new_data_flag = false;

// check for "connect" cmd
if (strcmp_ign(cli_h->cli_rx_buffer, (uint8_t *)"connect") == 0) {
cli_h->cli_connected_flag = true;
LOGD("Connection confirmed");
}
//check for "dfu" cmd
if (strcmp_ign(cli_h->cli_rx_buffer, (uint8_t *)"dfu") == 0) {
reboot_into_dfu();
}
}
}
}
}

void cli_handle_cmd(cli_handle_t *cli_h) {
// find the command index
uint8_t *raw_cmd_str = cli_h->cli_rx_buffer;

// take first word as command
uint8_t *cmd_str = (uint8_t *)strtok((char *)raw_cmd_str, " ");

//clean arg array
for (int i = 0; i < MAX_ARGS_COUNT; i++) {
cli_h->last_args[i] = (uint8_t*)"";
}

// array to hold the arguments
uint8_t arg_count = 0;

// get the rest of the arguments
while (arg_count < MAX_ARGS_COUNT) {
cli_h->last_args[arg_count] = (uint8_t *)strtok(NULL, " ");
if (cli_h->last_args[arg_count] == NULL) {
break;
}
clean_str(cli_h->last_args[arg_count]); // removes any \n or \r
arg_count++;
}
cli_h->last_args_count = arg_count; //save last count so cmd callbacks know how many args there are

int8_t cmd_index = -1;

for (int8_t i = 0; i < MAX_CMD_COUNT; i++) {
if (cli_h->cmd_list[i].cmd_str != NULL) {
if (strcmp_ign(cli_h->cmd_list[i].cmd_str, cmd_str) == 0) {
cmd_index = i;
break;
}
}
}

if (cmd_index == -1) {
LOGE("The command you entered does not exist: %s, try again", cmd_str);
return;
}

if (cli_h->cmd_list[cmd_index].cmd_callback != NULL) {
cli_h->cmd_list[cmd_index].cmd_callback(cli_h);
} else {
LOGE("The command you entered has no callback, it is most likely not implemented yet: %s", cmd_str);
}
}


void cli_add_cmd(cli_handle_t *cli_h, uint8_t *cmd_str, callback_t cmd_callback) {
//check if cmd_str is already an existing command
for (size_t i = 0; i < MAX_CMD_COUNT; i++) {
if (strcmp_ign(cmd_str, (uint8_t *)cli_h->cmd_list[i].cmd_str) == 0) {
LOGE((uint8_t *)"Command already exists, not adding... %s", cmd_str);
return;
}
}

//find an empty slot in the command list
for (size_t i = 0; i < MAX_CMD_COUNT; i++) {
if (cli_h->cmd_list[i].cmd_str == NULL) {
cli_h->cmd_list[i].cmd_str = cmd_str;
cli_h->cmd_list[i].cmd_callback = cmd_callback;

if (cmd_callback == NULL) {
LOGW((uint8_t *)"Command added without callback: %s", cmd_str);
return;
}

LOGD((uint8_t *)"Command added: %s", cmd_str);
return;
}
}

LOGE((uint8_t *)"No empty slot found for command %s, Increase MAX_CMD_COUNT", cmd_str);
}

// cli_rx_callback gets called when cli_rx_buffer gets updated with new data
void cli_rx_callback(cli_handle_t* cli_h) {
cli_h->new_data_flag = true;
// don't copy data here... will break receive function.
//TODO: Add a true callback...
}
39 changes: 39 additions & 0 deletions software/MySrc/Common/cli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Created by Isaak on 2/21/2024.
//

#ifndef BETTERFLIGHT_CLI_H
#define BETTERFLIGHT_CLI_H

#include "version.h"
#include "misc.h"

#define MAX_CMD_COUNT 64
#define MAX_ARGS_COUNT 16

typedef struct {
uint8_t *cmd_str;
callback_t cmd_callback;
}cli_cmd_t;

typedef struct {
cli_cmd_t cmd_list[MAX_CMD_COUNT];
version_t version;
uint8_t cli_rx_buffer[64];
uint8_t cli_tx_buffer[64];
bool new_data_flag;
bool cli_connected_flag;
bool halt_until_connected_flag;
uint8_t last_cmd_index;
uint8_t *last_args[MAX_ARGS_COUNT];
uint8_t last_args_count;
} cli_handle_t;

void cli_init(cli_handle_t *cli_h);
void cli_process(void *arg);

void cli_rx_callback(cli_handle_t* cli_h);
void cli_add_cmd(cli_handle_t* cli_h, uint8_t *cmd_str, callback_t cmd_callback);


#endif //BETTERFLIGHT_CLI_H
178 changes: 178 additions & 0 deletions software/MySrc/Common/cli_cmd_callbacks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
This file is part of the CLI module.
It contains the callback functions that are called when a command is received.
You have to be here and NOT IN CLI.C to add new commands
To add a command:
1. Add a new callback function
2. Add the callback function and cli command string to the add_commands function (below cb's)
*/

#include "cli_cmd_callbacks.h"

#include <stdint.h>
#include <stdio.h>

#include "cli.h"
#include "log.h"
#include "version.h"
#include "misc.h"
#include "main.h"
#include "mymain.h"
#include "motors.h"


void cli_cb_status(cli_handle_t *cli_h) {
LOGI("Status: OK");
}

void cli_cb_help(cli_handle_t *cli_h) {
LOG("[RSP] Available commands:");
for (uint8_t i = 0; i < MAX_CMD_COUNT; i++) {
if (cli_h->cmd_list[i].cmd_str != NULL) {
LOG("%s", cli_h->cmd_list[i].cmd_str);
}
}
}

void cli_cb_dfu(cli_handle_t *cli_h) {
LOGI("Rebooting into DFU mode...");
reboot_into_dfu();
}

void cli_cb_reboot(cli_handle_t *cli_h) {
LOGI("Rebooting...");
HAL_Delay(100); //wait for msg to be sent
NVIC_SystemReset();
}

void cli_cb_version(cli_handle_t *cli_h) {
uint8_t version_string[10];
VERSION_TO_STRING(CLI_VERSION, version_string);
LOG("[RSP] %s", version_string);
}

void cli_cb_connect(cli_handle_t *cli_h) {
LOG((uint8_t *) "[RSP] Confirm Connection");
cli_h->cli_connected_flag = true;
}

void cli_cb_disconnect(cli_handle_t *cli_h) {
LOG((uint8_t *) "[RSP] Confirm Disconnection");
cli_h->cli_connected_flag = false;
}

void cli_cb_clidemo(cli_handle_t *cli_h) {
LOGD("This is a Debug message");
LOGI("This is an Info message");
LOGW("This is a Warning message");
LOGE("This is an Error message");
LOG("This is a normal message (should not be used...)");
LOG("[RSP] This is a response message to a cli command");
}

callback_t cli_cb_none(cli_handle_t *cli_h) {
LOGI("Command not implemented yet");
}

// --- MOTORS --- //

void cli_cb_set_motor(cli_handle_t *cli_h) {
LOG("[RSP] Setting motor %s to %s", (char*)cli_h->last_args[0], (char*)cli_h->last_args[1]);

if (cli_h->last_args_count != 2) {
LOGE("Invalid number of arguments, 2 expected");
return;
}

uint8_t motor_nr = char_to_uint16((char*)cli_h->last_args[0]);
if (motor_nr < 1 || motor_nr > 4) {
LOGE("Invalid motor number, 1 to 4 expected");
return;
}

uint16_t motor_value = char_to_uint16((char*)cli_h->last_args[1]);
motor_set_throttle(&motors_h, motor_nr, motor_value);
}

void cli_cb_set_motors(cli_handle_t *cli_h) {
uint16_t motor_values[4];
if (cli_h->last_args_count == 1) {
for (uint8_t i = 0; i < 4; i++) {
motor_values[i] = (char_to_uint16((char*)cli_h->last_args[0]));
}
} else if (cli_h->last_args_count == 4) {
for (uint8_t i = 0; i < 4; ++i) {
motor_values[i] = (char_to_uint16((char*)cli_h->last_args[i]));
delay(1);
}
} else {
LOGE("Invalid number of arguments, 1 to set all motors to the same value, 4 to set each motor individually!");
return;
}

LOG("[RSP] Set Motor valuese to: m1: %d m2: %d m3: %d m4: %d", motor_values[0], motor_values[1], motor_values[2], motor_values[3]);
motors_set_throttle_arr(&motors_h, motor_values);
}


void cli_cb_stop_motors(cli_handle_t *cli_h) {
motors_stop(&motors_h);
LOG("[RSP] Motors stopped");
}

void cli_cb_beep_motors(cli_handle_t *cli_h) {
motors_beep(&motors_h);
LOG("[RSP] Motors beeped");
}

void cli_cb_set_motor_direction(cli_handle_t *cli_h) {
LOG("[RSP] Setting motor (%s) direction to %s", (char*)cli_h->last_args[0], (char*)cli_h->last_args[1]);

if (cli_h->last_args_count != 2) {
LOGE("Invalid number of arguments, 2 expected");
return;
}

uint8_t motor_nr = char_to_uint16((char*)cli_h->last_args[0]);
if (motor_nr < 1 || motor_nr > 4) {
LOGE("Invalid motor number, 1 to 4 expected");
return;
}

bool motor_dir = char_to_uint16((char*)cli_h->last_args[1]);
if (motor_dir != 0 && motor_dir != 1) {
LOGE("Invalid motor direction, 0 or 1 expected");
return;
}

motor_set_direction(&motors_h, motor_nr, motor_dir);
}

// --- EOF MOTORS --- //

void cli_cb_sendsc(cli_handle_t *cli_h) {
LOG("[RSP] Sending motor %d cmd %d" , char_to_uint16((char*)cli_h->last_args[0]), char_to_uint16((char*)cli_h->last_args[1]));
dshot_send_special_command(motors_h.dshot_hs[char_to_uint16((char*)cli_h->last_args[0]) - 1], char_to_uint16((char*)cli_h->last_args[1]));
}


void add_commands(cli_handle_t *cli_h) {
cli_add_cmd(cli_h, (uint8_t *)"help", (callback_t) cli_cb_help);
cli_add_cmd(cli_h, (uint8_t *)"status", (callback_t) cli_cb_status);
cli_add_cmd(cli_h, (uint8_t *)"version", (callback_t) cli_cb_version);
cli_add_cmd(cli_h, (uint8_t *)"connect", (callback_t) cli_cb_connect);
cli_add_cmd(cli_h, (uint8_t *)"save", NULL);
cli_add_cmd(cli_h, (uint8_t *)"dfu", (callback_t) cli_cb_dfu);
cli_add_cmd(cli_h, (uint8_t *)"reboot", (callback_t) cli_cb_reboot);
cli_add_cmd(cli_h, (uint8_t *)"disconnect", (callback_t) cli_cb_disconnect);
cli_add_cmd(cli_h, (uint8_t *)"demo", (callback_t) cli_cb_clidemo);
cli_add_cmd(cli_h, (uint8_t *)"setmotor", (callback_t) cli_cb_set_motor);
cli_add_cmd(cli_h, (uint8_t *)"setmotors", (callback_t) cli_cb_set_motors);
cli_add_cmd(cli_h, (uint8_t *)"stopmotors", (callback_t) cli_cb_stop_motors);
cli_add_cmd(cli_h, (uint8_t *)"beepmotors", (callback_t) cli_cb_beep_motors);
cli_add_cmd(cli_h, (uint8_t *)"setmotordir", (callback_t) cli_cb_set_motor_direction);
cli_add_cmd(cli_h, (uint8_t *)"sendsc", (callback_t) cli_cb_sendsc);
}
12 changes: 12 additions & 0 deletions software/MySrc/Common/cli_cmd_callbacks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Created by Isaak on 2/27/2024.
//

#ifndef BETTERFLIGHT_CLI_CMD_CALLBACKS_H
#define BETTERFLIGHT_CLI_CMD_CALLBACKS_H

#include "cli.h"

void add_commands(cli_handle_t *cli_h);

#endif //BETTERFLIGHT_CLI_CMD_CALLBACKS_H
Loading

0 comments on commit 8fbbf38

Please sign in to comment.