Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First instance of ADC CLI, still need to add help messages #329

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified hooks/pre-commit
100644 → 100755
Empty file.
11 changes: 11 additions & 0 deletions projects/uart_cli/inc/adc_cli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include <stdbool.h>

#include "cli_base.h"

void adc_cmd(char *input);

bool adc_valid_addr(char *port);
bool adc_valid_state(char *state);
int adc_valid_pin_mode(char *pin_mode);
bool adc_state_to_int(char *state);
1 change: 1 addition & 0 deletions projects/uart_cli/inc/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ the keyword for an action to the corresponding prv function
*/

#include "gpio_cli.h"
#include "adc_cli.h"

void cli_init();
void cli_run();
Expand Down
236 changes: 236 additions & 0 deletions projects/uart_cli/src/adc_cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#include "adc_cli.h"

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "adc.h"
#include "log.h"
#include "string.h"

static const char adc_help[] =
"CLI Reference for GPIO Pins. Usage: \n\r"
"adc <add/run/raw/converted> <parameters> \n\r\n"

"Commands:\n\r"
" - add: Initialize an ADC channel\n\r"
" - run: Start ADC conversions on all initialized channels\n\r"
" - raw: Read raw ADC values from a specified channel\n\r"
" - converted: Read converted (processed) ADC values\n\r\n"

"Type \"help\" after any action for detailed reference.\n\r";

static const char adc_add_help[] =
"Usage: Add an ADC channel by specifying the pin and mode. \n\r"
"adc add <address> <mode> \n\r\n"

"Address: <Port (A, B)><Pin (0-7 for A, 0-1 for B)> \n\r"
"Examples: A0, A7, B1\n\r\n"

"Pin Modes: \"analog\", \"input_floating\", \"input_pull_down\", \n\r"
"\"input_pull_up\", \"output_open_drain\", \"output_push_pull\", \n\r"
"\"altfn_open_drain\", \"altfn_push_pull\" \n\r\n"

"Example: adc add A0 analog\n\r";

static const char adc_run_help[] =
"Usage: Start ADC conversions on all initialized channels. \n\r"
"adc run\n\r";

static const char adc_read_converted_help[] =
"Usage: Read converted (processed) ADC values from the specified channel. \n\r"
"adc converted <address>\n\r\n"

"Address: <Port (a-b)><Pin (0-7 for a, 0-1 for b)> \n\r"
"Example: adc converted A0\n\r";

static const char adc_read_raw_help[] =
"Usage: Read raw ADC values from the specified channel. \n\r"
"adc raw <address>\n\r\n"

"Address: <Port (a-b)><Pin (0-7 for a, 0-1 for b)> \n\r"
"Example: adc raw A0\n\r";

static void prv_add_channel(char *args) {
char addr[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(args, addr);
char pin_mode[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(args, pin_mode);

int pin_mode_enum = adc_valid_pin_mode(pin_mode);
char *state_str = args;

if (strcmp(addr, "help") == 0 || strcmp(addr, "h") == 0) {
printf("\r%s\n", adc_add_help);
return;
} else if (!(adc_valid_addr(addr) && adc_valid_state(state_str))) {
printf("\r%s\n", adc_add_help);
return;
} else if (!(adc_valid_addr(addr) && (pin_mode_enum != NUM_GPIO_MODES) &&
adc_valid_pin_port(state_str))) {
printf("Invalid pin mode\n\r");
printf("\r%s\n", adc_add_help);
return;
}

GpioAddress address = { .port = addr[0] - 97, .pin = strtol(addr + 1, NULL, 10) };

if (adc_add_channel(address) == STATUS_CODE_OK) {
printf("SUCCESS\n\r");
} else {
printf("FAILED\n\r");
}
}

static void prv_run(char *args) {
char addr[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(args, addr);

if (strcmp(addr, "help") == 0 || strcmp(addr, "h") == 0) {
printf("\r%s\n", adc_run_help);
return;
}

if (adc_run() == STATUS_CODE_OK) {
printf("SUCCESS\n\r");
} else {
printf("FAILED\n\r");
}
}

static void prv_read_raw(char *args) {
char *addr = args;
char pin_mode[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(args, pin_mode);

int pin_mode_enum = adc_valid_pin_mode(pin_mode);
char *state_str = args;

if (strcmp(addr, "help") == 0 || strcmp(addr, "h") == 0) {
printf("\r%s\n", adc_read_raw_help);
return;
} else if (!adc_valid_addr(addr)) {
printf("\r%s\n", adc_read_raw_help);
return;
} else if (!(adc_valid_addr(addr) && (pin_mode_enum != NUM_GPIO_MODES) &&
adc_valid_pin_port(state_str))) {
printf("Invalid pin mode\n\r");
printf("\r%s\n", adc_read_raw_help);
return;
}

GpioAddress address = { .port = addr[0] - 97, .pin = strtol(addr + 1, NULL, 10) };
uint16_t reading;

if (adc_read_raw(address, &reading) == STATUS_CODE_OK) {
printf("\r%d\n", reading);
} else {
printf("FAILED\n\r");
}
}

static void prv_read_converted(char *args) {
char *addr = args;
char pin_mode[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(args, pin_mode);

int pin_mode_enum = adc_valid_pin_mode(pin_mode);
char *state_str = args;

if (strcmp(args, "help") == 0 || strcmp(args, "h") == 0) {
printf("\r%s\n", adc_read_converted_help);
return;
} else if (!(adc_valid_addr(args))) {
printf("\r%s\n", adc_read_converted_help);
return;
} else if (!(adc_valid_addr(addr) && (pin_mode_enum != NUM_GPIO_MODES) &&
adc_valid_pin_port(state_str))) {
printf("Invalid pin mode\n\r");
printf("\r%s\n", adc_read_converted_help);
return;
}

GpioAddress address = { .port = args[0] - 97, .pin = strtol(args + 1, NULL, 10) };
uint16_t reading;

if (adc_read_converted(address, &reading) == STATUS_CODE_OK) {
printf("\r%d\n", reading);
} else {
printf("FAILED\n\r");
}
}

bool adc_valid_addr(char *addr) {
if (addr[0] < 97 || addr[0] > 103) {
printf("Invalid port - must be a value from a to g\n\r");
return false;
}

char *end_ptr = NULL;
const uint8_t pin = strtol(addr + 1, &end_ptr, 10);

if (pin > 15 || *end_ptr != '\0') {
printf("Invalid pin - must be a value from 0 to 15\n\r");
return false;
}

return true;
}

//Replace with valid adc pin
//Assuming we're using STM32F103C8T6 which has PA0-PA7, PB0, PB1 as ADC pins
bool adc_valid_pin_port(char *state_str) {
char port = strtol(state_str[1], NULL, 10);
char pin = state_str[0] - 97;
if (port == 'A' && pin >= 0 && pin < 8) {
return true;
}
if (port == 'B' && pin >= 0 && pin < 2) {
return true;
}
return false;
}

int adc_valid_pin_mode(char *pin_mode) {
const char *pin_modes[NUM_GPIO_MODES] = {
"analog", "input_floating", "input_pull_down", "input_pull_up", "output_open_drain",
"output_push_pull", "alftn_open_drain", "altfn_push_pull"
};

for (int i = 0; i < NUM_GPIO_MODES; ++i) {
if (strcmp(pin_mode, pin_modes[i]) == 0) {
return i;
}
}
return NUM_GPIO_MODES;
}

bool adc_state_to_int(char *state) {
return strcmp(state, "low");
}

static const CmdStruct adc_lookup[] = { { .cmd_name = "add", .cmd_func = &prv_add_channel },
{ .cmd_name = "run", .cmd_func = &prv_run },
{ .cmd_name = "raw", .cmd_func = &prv_read_raw },
{ .cmd_name = "converted",
.cmd_func = &prv_read_converted } };

void adc_cmd(char *cmd) {
char action[MAX_CMD_LEN + 1] = { 0 };
tok_cmd(cmd, action);

if (strcmp(action, "help") == 0 || strcmp(action, "h") == 0) {
printf("\r%s\n", adc_help);
return;
}

for (size_t i = 0; i < SIZEOF_ARRAY(adc_lookup); ++i) {
if (strcmp(action, adc_lookup[i].cmd_name) == 0) {
adc_lookup[i].cmd_func(cmd);
return;
}
}
// ERROR: Invalid action
printf("Invalid action\n\r");
printf("\r%s\n", adc_help);
}
3 changes: 2 additions & 1 deletion projects/uart_cli/src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ static const char cli_help[] =

static char cmd_buffer[MAX_CMD_LEN + 1];
// Add additional peripherals to lookup array
static const CmdStruct cmd_lookup[] = { { .cmd_name = "gpio", .cmd_func = &gpio_cmd } };
static const CmdStruct cmd_lookup[] = { { .cmd_name = "gpio", .cmd_func = &gpio_cmd },
{.cmd_name = "adc", .cmd_func = &adc_cmd} };

void cli_init() {
// Add peripheral init calls here
Expand Down
Loading