tools/ftdi_transfer: add help/usage

This commit is contained in:
Zack Buhman 2024-12-08 17:29:30 -06:00
parent d2c28febd7
commit eeb2de8de1

View File

@ -338,7 +338,7 @@ int do_jump(struct ftdi_context * ftdi, const uint32_t dest)
return 0;
}
int do_show_baudrate_error(struct ftdi_context * ftdi, uint32_t rows)
int do_show_baudrate_error(struct ftdi_context * ftdi)
{
/*
B = (390625 * 4^(1 - n)) / (N + 1)
@ -349,7 +349,8 @@ int do_show_baudrate_error(struct ftdi_context * ftdi, uint32_t rows)
fprintf(stderr, " ------------|-------------|---------\n");
unsigned short value;
unsigned short index;
rows = min(rows, 256);
//rows = min(rows, 256);
const int rows = 256;
for (uint32_t i = 0; i < rows; i++) {
int baud = convert_baudrate_UT_export(dreamcast_rate(0, i), ftdi, &value, &index);
if (baud < 0) {
@ -368,13 +369,14 @@ int do_show_baudrate_error(struct ftdi_context * ftdi, uint32_t rows)
return 0;
}
int do_list_baudrates(struct ftdi_context * ftdi, uint32_t rows)
int do_list_baudrates(struct ftdi_context * ftdi)
{
(void)ftdi;
fprintf(stderr, " scbrr | cks 0 | cks 1 | cks 2 | cks 3\n");
fprintf(stderr, "---------------------------------------------------------\n");
rows = min(rows, 256);
//rows = min(rows, 256);
const int rows = 256;
for (uint32_t i = 0; i < rows; i++) {
fprintf(stderr, " 0x%02x % 11.2f % 11.2f % 11.2f % 11.2f\n",
i,
@ -662,23 +664,52 @@ enum struct argument_type {
integer
};
struct usage_example {
const char * usage;
const char * example;
};
struct cli_command {
const char * name;
int num_arguments;
void * func;
bool need_ftdi_init;
const struct usage_example * usage_example;
};
struct cli_command commands[] = {
{ "read" , 3, (void *)&do_read },
{ "write" , 2, (void *)&do_write },
{ "jump" , 1, (void *)&do_jump },
{ "speed" , 1, (void *)&do_speed },
{ "console" , 0, (void *)&do_console },
{ "maple_storage_dump" , 0, (void *)&do_maple_storage_dump },
{ "list_baudrates" , 1, (void *)&do_list_baudrates },
{ "show_baudrate_error", 1, (void *)&do_show_baudrate_error },
constexpr struct usage_example read_help = {
"SRC_ADDR READ_SIZE FILENAME",
"0xa5000000 0x800000 ./texture_memory.bin",
};
constexpr struct usage_example write_help = {
"DEST_ADDR FILENAME",
"0xac010000 ./program.bin",
};
constexpr struct usage_example jump_help = {
"JUMP_ADDR",
"0xac010000",
};
constexpr struct usage_example speed_help = {
"SCBRR",
"0x0",
};
void do_help();
const struct cli_command commands[] = {
{ "read" , 3, (void *)&do_read , true, &read_help},
{ "write" , 2, (void *)&do_write , true, &write_help},
{ "jump" , 1, (void *)&do_jump , true, &jump_help},
{ "speed" , 1, (void *)&do_speed , true, &speed_help},
{ "console" , 0, (void *)&do_console , true, NULL},
{ "maple_storage_dump" , 0, (void *)&do_maple_storage_dump , true, NULL},
{ "list_baudrates" , 0, (void *)&do_list_baudrates , false, NULL},
{ "show_baudrate_error", 0, (void *)&do_show_baudrate_error , true, NULL},
{ "help" , 0, (void *)&do_help , false, NULL},
};
constexpr int commands_length = (sizeof (commands)) / (sizeof (commands[0]));
typedef int (*func_0_arg)(struct ftdi_context *);
@ -728,9 +759,19 @@ int parse_integer(const char * s, uint32_t * value)
return 0;
}
void short_help(const struct cli_command * command)
{
if (commands->usage_example != NULL) {
printf("\nusage:\n\n");
printf(" %s %s\n\n", command->name, command->usage_example->usage);
printf(" %s %s\n\n", command->name, command->usage_example->example);
}
}
#define CHECK_ARGC(__name__) \
if (arg_index >= argc) { \
fprintf(stderr, "while processing command `%s` expected argument `%s`\n", name, #__name__); \
short_help(&commands[i]); \
return -1; \
}
@ -741,6 +782,7 @@ int parse_integer(const char * s, uint32_t * value)
{ int res = parse_integer(__name__##str, &__name__); \
if (res < 0) { \
fprintf(stderr, "while processing command `%s` expected integer at `%s`", name, __name__##str); \
short_help(&commands[i]); \
return -1; \
} }
@ -748,7 +790,7 @@ int parse_integer(const char * s, uint32_t * value)
CHECK_ARGC(__name__); \
const char * __name__ = argv[arg_index++];
int handle_command(int argc, const char * argv[], struct ftdi_context * ftdi)
int handle_command(int argc, const char * argv[], struct ftdi_context * ftdi, bool * ftdi_init_done)
{
assert(argc >= 1);
int arg_index = 0;
@ -757,13 +799,20 @@ int handle_command(int argc, const char * argv[], struct ftdi_context * ftdi)
for (int i = 0; i < commands_length; i++) {
if (strcmp(commands[i].name, name) == 0) {
if (!(*ftdi_init_done) && commands[i].need_ftdi_init) {
int res;
res = init_ftdi_context(ftdi, 0);
if (res < 0) {
return -1;
}
*ftdi_init_done = true;
}
switch (commands[i].num_arguments) {
case 0:
{
fprintf(stderr, "handle command: %s ()\n", commands[i].name);
func_0_arg func = (func_0_arg)commands[i].func;
fprintf(stderr, "%p\n", &do_console);
fprintf(stderr, "%p\n", func);
func_ret = func(ftdi);
}
break;
@ -829,12 +878,39 @@ int handle_command(int argc, const char * argv[], struct ftdi_context * ftdi)
}
fprintf(stderr, "unknown command `%s`\n", name);
do_help();
return -1;
}
static const char * argv_0;
void do_help()
{
printf("\nusage: %s [command ...]\n\n", argv_0);
printf("where [command] is one or more of:\n\n");
for (int i = 0; i < commands_length; i++) {
printf(" %s", commands[i].name);
if (commands[i].usage_example != NULL) {
printf(" %s", commands[i].usage_example->usage);
}
printf("\n");
}
printf("\nexamples for commands that have arguments:\n\n");
for (int i = 0; i < commands_length; i++) {
if (commands[i].usage_example != NULL) {
printf(" %s %s\n", commands[i].name, commands[i].usage_example->example);
}
}
printf("\nnote: all integers are given in base 16; the `0x` prefix is optional and may be omitted.\n");
}
int main(int argc, const char * argv[])
{
argv_0 = argv[0];
struct ftdi_context * ftdi;
bool ftdi_init_done = false;
ftdi = ftdi_new();
if (ftdi == 0) {
@ -842,17 +918,11 @@ int main(int argc, const char * argv[])
return EXIT_FAILURE;
}
int res;
res = init_ftdi_context(ftdi, 0);
if (res < 0) {
return EXIT_FAILURE;
}
assert(argc >= 1);
argc--;
argv++;
while (argc > 0) {
res = handle_command(argc, argv, ftdi);
int res = handle_command(argc, argv, ftdi, &ftdi_init_done);
if (res < 0) {
return -1;
}