You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

966 lines
20 KiB

#include "app_cli.h"
#include "sw_timer.h"
#include "app_uart.h"
3 months ago
#include "ak9757w.h"
#include <stdlib.h>
3 months ago
#include "app_log.h"
#define CLI_KEY_BACK 0x7F
#define CLI_KEY_DEL 0x7E
#define CLI_KEY_ENTER 0x0D
#define CLI_KEY_ESC 0x1B
#define CLI_KEY_LEFT 0x44
#define CLI_KEY_RIGHT 0x43
#define CLI_KEY_UP 0x41
#define CLI_KEY_DOWN 0x42
#define CLI_KEY_HOME 0x31
#define CLI_KEY_END 0x34
#define CLI_PROMPT_STR "CLI# "
#define CLI_ARGS_MAX 32
#define CLI_PRINT_BUF_MAX 256
enum
{
CLI_RX_IDLE,
CLI_RX_SP1,
CLI_RX_SP2,
CLI_RX_SP3,
CLI_RX_SP4,
};
typedef struct
{
char cmd_str[CLI_CMD_NAME_MAX];
void (*cmd_func)(cli_args_t *);
} cli_cmd_t;
typedef struct
{
uint8_t buf[CLI_LINE_BUF_MAX];
uint8_t buf_len;
uint8_t cursor;
uint8_t count;
} cli_line_t;
typedef struct
{
bool is_open;
bool is_log;
uint8_t log_ch;
uint32_t log_baud;
uint8_t state;
char print_buffer[CLI_PRINT_BUF_MAX];
uint16_t argc;
char *argv[CLI_ARGS_MAX];
bool hist_line_new;
int8_t hist_line_i;
uint8_t hist_line_last;
uint8_t hist_line_count;
cli_line_t line_buf[CLI_LINE_HIS_MAX];
cli_line_t line;
uint16_t cmd_count;
cli_cmd_t cmd_list[CLI_CMD_LIST_MAX];
cli_args_t cmd_args;
} cli_t;
cli_t cli_node;
static bool cliUpdate(cli_t *p_cli, uint8_t rx_data);
static void cliLineClean(cli_t *p_cli);
static void cliLineAdd(cli_t *p_cli);
static void cliLineChange(cli_t *p_cli, int8_t key_up);
static void cliShowPrompt(cli_t *p_cli);
static void cliToUpper(char *str);
static bool cliRunCmd(cli_t *p_cli);
static bool cliParseArgs(cli_t *p_cli);
static int32_t cliArgsGetData(uint8_t index);
static float cliArgsGetFloat(uint8_t index);
static char *cliArgsGetStr(uint8_t index);
static bool cliArgsIsStr(uint8_t index, char *p_str);
static void uartPrintf(const char *format, ...);
static uint32_t uartWrite(uint8_t* pTxData, uint32_t txLen);
void cliShowList(cli_args_t *args);
void cliMemoryDump(cli_args_t *args);
3 months ago
void cli_AKM_Cmd(cli_args_t *args);
bool cliInit(void);
void cliMain(void);
bool cliAdd(const char *cmd_str, void (*p_func)(cli_args_t *));
void cliPrintf(const char *fmt, ...);
#if 0
bool cliOpen(uint8_t ch, uint32_t baud);
bool cliOpenLog(uint8_t ch, uint32_t baud);
bool cliAdd(const char *cmd_str, void (*p_func)(cli_args_t *));
bool cliKeepLoop(void);
uint32_t cliAvailable(void);
uint8_t cliRead(void);
uint32_t cliWrite(uint8_t *p_data, uint32_t length);
#endif
void App_CLI_Initialization(void)
{
cliInit();
SW_Timer_Callback_Register(SW_TIMER_RUN_CONTINUE, 0, cliMain);
}
bool cliInit(void)
{
cli_node.is_open = true;
cli_node.is_log = true;
cli_node.state = CLI_RX_IDLE;
cli_node.hist_line_i = 0;
cli_node.hist_line_last = 0;
cli_node.hist_line_count = 0;
cli_node.hist_line_new = false;
cli_node.cmd_args.getData = cliArgsGetData;
cli_node.cmd_args.getFloat = cliArgsGetFloat;
cli_node.cmd_args.getStr = cliArgsGetStr;
cli_node.cmd_args.isStr = cliArgsIsStr;
cliLineClean(&cli_node);
cliAdd("help", cliShowList);
cliAdd("md" , cliMemoryDump);
3 months ago
cliAdd("akm" , cli_AKM_Cmd);
return true;
}
#if 0
bool cliOpen(uint8_t ch, uint32_t baud)
{
cli_node.ch = ch;
cli_node.baud = baud;
cli_node.is_open = uartOpen(ch, baud);
return cli_node.is_open;
}
bool cliOpenLog(uint8_t ch, uint32_t baud)
{
bool ret;
cli_node.log_ch = ch;
cli_node.log_baud = baud;
ret = uartOpen(ch, baud);
if (ret == true)
{
cli_node.is_log = true;
}
return ret;
}
bool cliLogClose(void)
{
cli_node.is_log = false;
return true;
}
#endif
void cliShowLog(cli_t *p_cli)
{
if (cli_node.is_log == true)
{
uartPrintf("Cursor : %d\r\n", p_cli->line.cursor);
uartPrintf("Count : %d\r\n", p_cli->line.count);
uartPrintf("buf_len : %d\r\n", p_cli->line.buf_len);
uartPrintf("buf : %s\r\n", p_cli->line.buf);
uartPrintf("line_i : %d\r\n", p_cli->hist_line_i);
uartPrintf("line_lt : %d\r\n", p_cli->hist_line_last);
uartPrintf("line_c : %d\r\n", p_cli->hist_line_count);
for (int i=0; i<p_cli->hist_line_count; i++)
{
uartPrintf("buf %d : %s\r\n", i, p_cli->line_buf[i].buf);
}
uartPrintf("\r\n");
}
}
void cliShowPrompt(cli_t *p_cli)
{
uartPrintf("\n\r");
3 months ago
uartPrintf(CLI_PROMPT_STR);
}
void cliMain(void)
{
#if 0
if (cli_node.is_open != true)
{
return false;
}
#endif
#if 0
if(uartAvailable(cli_node.ch) > 0)
{
cliUpdate(&cli_node, uartRead(cli_node.ch));
}
return true;
#endif
uint8_t RxData;
if(App_Uart_Get_Recv_Data(&RxData) == true)
{
cliUpdate(&cli_node, RxData);
}
}
uint32_t cliAvailable(void)
{
#if 0
return uartAvailable(cli_node.ch);
#endif
return 0;
}
uint8_t cliRead(void)
{
#if 0
return uartRead(cli_node.ch);
#endif
return 0;
}
uint32_t cliWrite(uint8_t *p_data, uint32_t length)
{
#if 0
return uartWrite(cli_node.ch, p_data, length);
#endif
return 0;
}
bool cliUpdate(cli_t *p_cli, uint8_t rx_data)
{
bool ret = false;
uint8_t tx_buf[8];
cli_line_t *line;
line = &p_cli->line;
if (p_cli->state == CLI_RX_IDLE)
{
switch(rx_data)
{
// 엔터
//
case CLI_KEY_ENTER:
if (line->count > 0)
{
cliLineAdd(p_cli);
cliRunCmd(p_cli);
}
line->count = 0;
line->cursor = 0;
line->buf[0] = 0;
cliShowPrompt(p_cli);
break;
case CLI_KEY_ESC:
p_cli->state = CLI_RX_SP1;
break;
// DEL
//
case CLI_KEY_DEL:
if (line->cursor < line->count)
{
uint8_t mov_len;
mov_len = line->count - line->cursor;
for (int i=1; i<mov_len; i++)
{
line->buf[line->cursor + i - 1] = line->buf[line->cursor + i];
}
line->count--;
line->buf[line->count] = 0;
uartPrintf("\x1B[1P");
}
break;
// 백스페이스
//
case CLI_KEY_BACK:
if (line->count > 0 && line->cursor > 0)
{
if (line->cursor == line->count)
{
line->count--;
line->buf[line->count] = 0;
}
if (line->cursor < line->count)
{
uint8_t mov_len;
mov_len = line->count - line->cursor;
for (int i=0; i<mov_len; i++)
{
line->buf[line->cursor + i - 1] = line->buf[line->cursor + i];
}
line->count--;
line->buf[line->count] = 0;
}
}
if (line->cursor > 0)
{
line->cursor--;
uartPrintf("\b \b\x1B[1P");
}
break;
default:
if ((line->count + 1) < line->buf_len)
{
if (line->cursor == line->count)
{
uartWrite(&rx_data, 1);
line->buf[line->cursor] = rx_data;
line->count++;
line->cursor++;
line->buf[line->count] = 0;
}
if (line->cursor < line->count)
{
uint8_t mov_len;
mov_len = line->count - line->cursor;
for (int i=0; i<mov_len; i++)
{
line->buf[line->count - i] = line->buf[line->count - i - 1];
}
line->buf[line->cursor] = rx_data;
line->count++;
line->cursor++;
line->buf[line->count] = 0;
uartPrintf("\x1B[4h%c\x1B[4l", rx_data);
}
}
break;
}
}
switch(p_cli->state)
{
case CLI_RX_SP1:
p_cli->state = CLI_RX_SP2;
break;
case CLI_RX_SP2:
p_cli->state = CLI_RX_SP3;
break;
case CLI_RX_SP3:
p_cli->state = CLI_RX_IDLE;
if (rx_data == CLI_KEY_LEFT)
{
if (line->cursor > 0)
{
line->cursor--;
tx_buf[0] = 0x1B;
tx_buf[1] = 0x5B;
tx_buf[2] = rx_data;
uartWrite(tx_buf, 3);
}
}
if (rx_data == CLI_KEY_RIGHT)
{
if (line->cursor < line->count)
{
line->cursor++;
tx_buf[0] = 0x1B;
tx_buf[1] = 0x5B;
tx_buf[2] = rx_data;
uartWrite(tx_buf, 3);
}
}
if (rx_data == CLI_KEY_UP)
{
cliLineChange(p_cli, true);
uartPrintf((char *)p_cli->line.buf);
}
if (rx_data == CLI_KEY_DOWN)
{
cliLineChange(p_cli, false);
uartPrintf((char *)p_cli->line.buf);
}
if (rx_data == CLI_KEY_HOME)
{
uartPrintf("\x1B[%dD", line->cursor);
line->cursor = 0;
p_cli->state = CLI_RX_SP4;
}
if (rx_data == CLI_KEY_END)
{
uint16_t mov_len;
if (line->cursor < line->count)
{
mov_len = line->count - line->cursor;
uartPrintf("\x1B[%dC", mov_len);
}
if (line->cursor > line->count)
{
mov_len = line->cursor - line->count;
uartPrintf("\x1B[%dD", mov_len);
}
line->cursor = line->count;
p_cli->state = CLI_RX_SP4;
}
break;
case CLI_RX_SP4:
p_cli->state = CLI_RX_IDLE;
break;
}
//cliShowLog(p_cli);
return ret;
}
void cliLineClean(cli_t *p_cli)
{
p_cli->line.count = 0;
p_cli->line.cursor = 0;
p_cli->line.buf_len = CLI_LINE_BUF_MAX - 1;
p_cli->line.buf[0] = 0;
}
void cliLineAdd(cli_t *p_cli)
{
p_cli->line_buf[p_cli->hist_line_last] = p_cli->line;
if (p_cli->hist_line_count < CLI_LINE_HIS_MAX)
{
p_cli->hist_line_count++;
}
p_cli->hist_line_i = p_cli->hist_line_last;
p_cli->hist_line_last = (p_cli->hist_line_last + 1) % CLI_LINE_HIS_MAX;
p_cli->hist_line_new = true;
}
void cliLineChange(cli_t *p_cli, int8_t key_up)
{
uint8_t change_i;
if (p_cli->hist_line_count == 0)
{
return;
}
if (p_cli->line.cursor > 0)
{
uartPrintf("\x1B[%dD", p_cli->line.cursor);
}
if (p_cli->line.count > 0)
{
uartPrintf("\x1B[%dP", p_cli->line.count);
}
if (key_up == true)
{
if (p_cli->hist_line_new == true)
{
p_cli->hist_line_i = p_cli->hist_line_last;
}
p_cli->hist_line_i = (p_cli->hist_line_i + p_cli->hist_line_count - 1) % p_cli->hist_line_count;
change_i = p_cli->hist_line_i;
}
else
{
p_cli->hist_line_i = (p_cli->hist_line_i + 1) % p_cli->hist_line_count;
change_i = p_cli->hist_line_i;
}
p_cli->line = p_cli->line_buf[change_i];
p_cli->line.cursor = p_cli->line.count;
p_cli->hist_line_new = false;
}
bool cliRunCmd(cli_t *p_cli)
{
bool ret = false;
if (cliParseArgs(p_cli) == true)
{
cliPrintf("\r\n");
cliToUpper(p_cli->argv[0]);
for (int i=0; i<p_cli->cmd_count; i++)
{
if (strcmp(p_cli->argv[0], p_cli->cmd_list[i].cmd_str) == 0)
{
p_cli->cmd_args.argc = p_cli->argc - 1;
p_cli->cmd_args.argv = &p_cli->argv[1];
p_cli->cmd_list[i].cmd_func(&p_cli->cmd_args);
break;
}
}
}
return ret;
}
bool cliParseArgs(cli_t *p_cli)
{
bool ret = false;
char *tok;
char *next_ptr;
uint16_t argc = 0;
static const char *delim = " \f\n\r\t\v";
char *cmdline;
char **argv;
p_cli->argc = 0;
cmdline = (char *)p_cli->line.buf;
argv = p_cli->argv;
argv[argc] = NULL;
for (tok = strtok_r(cmdline, delim, &next_ptr); tok; tok = strtok_r(NULL, delim, &next_ptr))
{
argv[argc++] = tok;
}
p_cli->argc = argc;
if (argc > 0)
{
ret = true;
}
return ret;
}
void cliPrintf(const char *fmt, ...)
{
va_list arg;
va_start (arg, fmt);
int32_t len;
cli_t *p_cli = &cli_node;
len = vsnprintf(p_cli->print_buffer, 256, fmt, arg);
va_end (arg);
uartWrite((uint8_t *)p_cli->print_buffer, len);
}
void cliToUpper(char *str)
{
uint16_t i;
uint8_t str_ch;
for (i=0; i<CLI_CMD_NAME_MAX; i++)
{
str_ch = str[i];
if (str_ch == 0)
{
break;
}
if ((str_ch >= 'a') && (str_ch <= 'z'))
{
str_ch = str_ch - 'a' + 'A';
}
str[i] = str_ch;
}
if (i == CLI_CMD_NAME_MAX)
{
str[i-1] = 0;
}
}
int32_t cliArgsGetData(uint8_t index)
{
int32_t ret = 0;
cli_t *p_cli = &cli_node;
if (index >= p_cli->cmd_args.argc)
{
return 0;
}
ret = (int32_t)strtoul((const char * ) p_cli->cmd_args.argv[index], (char **)NULL, (int) 0);
return ret;
}
float cliArgsGetFloat(uint8_t index)
{
float ret = 0.0;
cli_t *p_cli = &cli_node;
if (index >= p_cli->cmd_args.argc)
{
return 0;
}
ret = (float)strtof((const char * ) p_cli->cmd_args.argv[index], (char **)NULL);
return ret;
}
char *cliArgsGetStr(uint8_t index)
{
char *ret = NULL;
cli_t *p_cli = &cli_node;
if (index >= p_cli->cmd_args.argc)
{
return 0;
}
ret = p_cli->cmd_args.argv[index];
return ret;
}
bool cliArgsIsStr(uint8_t index, char *p_str)
{
bool ret = false;
cli_t *p_cli = &cli_node;
if (index >= p_cli->cmd_args.argc)
{
return 0;
}
if(strcmp(p_str, p_cli->cmd_args.argv[index]) == 0)
{
ret = true;
}
return ret;
}
bool cliKeepLoop(void)
{
cli_t *p_cli = &cli_node;
#if 0
if (uartAvailable(p_cli->ch) == 0)
{
return true;
}
else
{
return false;
}
#endif
}
bool cliAdd(const char *cmd_str, void (*p_func)(cli_args_t *))
{
bool ret = true;
cli_t *p_cli = &cli_node;
uint16_t index;
if (p_cli->cmd_count >= CLI_CMD_LIST_MAX)
{
return false;
}
index = p_cli->cmd_count;
strcpy(p_cli->cmd_list[index].cmd_str, cmd_str);
p_cli->cmd_list[index].cmd_func = p_func;
cliToUpper(p_cli->cmd_list[index].cmd_str);
p_cli->cmd_count++;
return ret;
}
void cliShowList(cli_args_t *args)
{
cli_t *p_cli = &cli_node;
cliPrintf("\r\n");
cliPrintf("---------- cmd list ---------\r\n");
for (int i=0; i<p_cli->cmd_count; i++)
{
cliPrintf(p_cli->cmd_list[i].cmd_str);
cliPrintf("\r\n");
}
cliPrintf("-----------------------------\r\n");
}
void cliMemoryDump(cli_args_t *args)
{
int idx, size = 16;
unsigned int *addr;
int idx1, i;
unsigned int *ascptr;
unsigned char asc[4];
int argc = args->argc;
char **argv = args->argv;
if(args->argc < 1)
{
cliPrintf(">> md addr [size] \n");
return;
}
if(argc > 1)
{
size = (int)strtoul((const char * ) argv[1], (char **)NULL, (int) 0);
}
addr = (unsigned int *)strtoul((const char * ) argv[0], (char **)NULL, (int) 0);
ascptr = (unsigned int *)addr;
cliPrintf("\n ");
for (idx = 0; idx<size; idx++)
{
if((idx%4) == 0)
{
cliPrintf(" 0x%08X: ", (unsigned int)addr);
}
cliPrintf(" 0x%08X", *(addr));
if ((idx%4) == 3)
{
cliPrintf (" |");
for (idx1= 0; idx1< 4; idx1++)
{
memcpy((char *)asc, (char *)ascptr, 4);
for (i=0;i<4;i++)
{
if (asc[i] > 0x1f && asc[i] < 0x7f)
{
cliPrintf("%c", asc[i]);
}
else
{
cliPrintf(".");
}
}
ascptr+=1;
}
cliPrintf("|\r\n ");
}
addr++;
}
}
3 months ago
void cli_AKM_Cmd(cli_args_t *args)
{
uint32_t updatetime;
int argc = args->argc;
char **argv = args->argv;
if(argc < 1)
{
cliPrintf(">> AKM CMD \r\n");
cliPrintf(">>\t CMD List \r\n");
cliPrintf(">>\t Start\r\n");
cliPrintf(">>\t Stop\r\n");
cliPrintf(">>\t SP (save parameter)\r\n");
cliPrintf(">>\t EP (erase parameter)\r\n");
cliPrintf(">>\t DP (display parameter)\r\n");
cliPrintf(">>\t ID\r\n");
cliPrintf(">>\t Update millisec\r\n");
cliPrintf(">>\t WR reg_addr data\r\n");
cliPrintf(">>\t RR reg_addr read len\r\n");
return;
}
if(argc == 1)
{
if(strcmp(argv[0], "start") == 0)
{
AK9757W_Start_Stop(true);
}
else if(strcmp(argv[0], "stop") == 0)
{
AK9757W_Start_Stop(false);
}
else if(strcmp(argv[0], "id") == 0)
{
cliPrintf("ID : %08X\r\n", AK9757W_GetID());
}
else if(strcmp(argv[0], "sp") == 0)
{
AK9757W_SaveParameter();
}
else if(strcmp(argv[0], "ep") == 0)
{
AK9757W_DeleteParameter();
}
else if(strcmp(argv[0], "dp") == 0)
{
AK9757W_DispalyParameter();
}
}
else if(argc == 2)
{
if(strcmp(argv[0], "update") == 0)
{
updatetime = (int)strtoul((const char * ) argv[1], (char **)NULL, (int) 0);
if(updatetime < 100)
{
cliPrintf(">>\t update time error\r\n");
}
else
{
AK9757W_UpdateTime(updatetime);
}
}
}
else if(argc == 3)
{
if(strcmp(argv[0], "rr") == 0)
{
uint32_t Addr;
uint32_t readSize;
uint8_t ReadBuff[100];
Addr = (int)strtoul((const char * ) argv[1], (char **)NULL, (int) 0);
readSize = (int)strtoul((const char * ) argv[2], (char **)NULL, (int) 0);
if((readSize == 0) || (Addr > 0xFF) || (readSize > 100))
return;
if(AK9757W_ReadReg(Addr, readSize, &ReadBuff[0]) == true)
{
uint8_t i;
cliPrintf("\r\n");
for(i = 0 ; i < readSize ; i++)
{
cliPrintf("%02X ", ReadBuff[i]);
if((i % 16) == 15)
cliPrintf("\r\n");
}
cliPrintf("\r\n");
}
}
else if(strcmp(argv[0], "wr") == 0)
{
uint32_t writeAddr;
uint32_t writeData;
writeAddr = (int)strtoul((const char * ) argv[1], (char **)NULL, (int) 0);
writeData = (int)strtoul((const char * ) argv[2], (char **)NULL, (int) 0);
if(writeAddr > 0xFF || writeData > 0xFF)
return;
AK9757W_WriteReg(writeAddr, writeData);
}
}
}
static void uartPrintf(const char *format, ...)
{
char buf[256];
va_list args;
int len;
uint32_t ret;
va_start(args, format);
len = vsnprintf(buf, 256, format, args);
ret = uartWrite((uint8_t *)buf, len);
va_end(args);
}
static uint32_t uartWrite(uint8_t* pTxData, uint32_t txLen)
{
App_Uart_Transmit_Len(pTxData, txLen);
return 0;
}