#ifndef __CLI_H__
#define __CLI_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include "stm32f4xx.h"

#define CLI_PORT     (GPIOB)
#define CLI_PIN_TX   (GPIO_Pin_10)
#define CLI_PIN_RX   (GPIO_Pin_11)

#define CLI_BAUDRATE (9600)

#define CLI_BUFF_TX_LEN (4096)
#define CLI_BUFF_RX_LEN (1024)

#define CLI_TX_STREAM DMA1_Stream3
#define CLI_RX_STREAM DMA1_Stream1

#define CLI_FORCE_FILTER_INPUT1 (0)
#define CLI_FORCE_FILTER_INPUT2 (1)
#define CLI_FORCE_FILTER_INPUT3 (2)
#define CLI_FORCE_FILTER_INPUT4 (3)

#define CLI_FORCE_FILTER_INPUT1_MASK (1 << CLI_FORCE_FILTER_INPUT1)
#define CLI_FORCE_FILTER_INPUT2_MASK (1 << CLI_FORCE_FILTER_INPUT2)
#define CLI_FORCE_FILTER_INPUT3_MASK (1 << CLI_FORCE_FILTER_INPUT3)
#define CLI_FORCE_FILTER_INPUT4_MASK (1 << CLI_FORCE_FILTER_INPUT4)

struct cli_data_s {
    uint16_t rx_len;
    uint16_t tx_len;
    char *buff_rx;
    char *buff_tx;
    uint32_t frame_cnt;
};

struct cli_data_comb_s {
    uint32_t force_available;
    uint32_t force_data[32];
};

extern struct cli_data_s cli_data;
extern struct cli_data_comb_s cli_data_comb;

void cli_init(void);
void cli_send_data(uint16_t len);
uint16_t cli_string_copy(char *dst, char *src);
uint16_t cli_string_copy_newline(char *dst, char *src);
uint8_t cli_string_is_same(char *str1, char *str2, uint16_t *len);
uint8_t cli_is_cmd(char *buff, uint8_t *cmd_idx, uint16_t *len);
uint16_t cli_cmd_process_help(char *buff, uint16_t len);
uint16_t cli_cmd_process_force(char *buff, uint16_t len);
uint16_t cli_cmd_process_print(char *buff, uint16_t len);
uint16_t cli_cmd_process_invalid(char *buff, uint16_t len);
uint16_t cli_cmd_process(char *buff);
void cli_loop(void);

#ifdef __cplusplus
}
#endif

#endif /* __CLI_H__ */
