215 lines
5.8 KiB
C
215 lines
5.8 KiB
C
/**
|
|
* @file uart_cmd.c
|
|
* @brief UART command interface via PB5(RX) / PB3(TX)
|
|
*/
|
|
|
|
#include "uart_cmd.h"
|
|
#include "printf.h"
|
|
#include <string.h>
|
|
|
|
//=============================================================================
|
|
// Constant Definition
|
|
//=============================================================================
|
|
#define UART_CMD_TX_PORT GPIOB
|
|
#define UART_CMD_TX_PIN GPIO_Pin_03
|
|
#define UART_CMD_TX_AF GPIO_AF_1
|
|
|
|
#define UART_CMD_RX_PORT GPIOB
|
|
#define UART_CMD_RX_PIN GPIO_Pin_05
|
|
#define UART_CMD_RX_AF GPIO_AF_1
|
|
|
|
//=============================================================================
|
|
// Global Data Definition
|
|
//=============================================================================
|
|
volatile char g_uart_rx_buf[UART_CMD_RX_BUF_SIZE];
|
|
volatile uint16_t g_uart_rx_idx = 0;
|
|
volatile bool g_uart_rx_complete = false;
|
|
|
|
static bool g_pwm_enabled = false;
|
|
static bool g_notify_enabled = false;
|
|
|
|
//=============================================================================
|
|
// Private Function Definition
|
|
//=============================================================================
|
|
|
|
/* printf library calls _putchar for each character */
|
|
void _putchar(char character)
|
|
{
|
|
UART_SendData(UART0, character);
|
|
UART_WaitTxFifoEmpty(UART0);
|
|
}
|
|
|
|
|
|
|
|
static int cmd_strcmp(const volatile char *buf, const char *cmd)
|
|
{
|
|
while (*cmd)
|
|
{
|
|
if (*buf != *cmd)
|
|
return 1;
|
|
buf++;
|
|
cmd++;
|
|
}
|
|
return (*buf != '\0');
|
|
}
|
|
|
|
static bool cmd_match_with_arg(const volatile char *buf, const char *prefix, const char **arg_out)
|
|
{
|
|
size_t len = strlen(prefix);
|
|
for (size_t i = 0; i < len; i++)
|
|
{
|
|
if (buf[i] != prefix[i])
|
|
return false;
|
|
}
|
|
if (buf[len] == ' ')
|
|
{
|
|
*arg_out = (const char *)&buf[len + 1];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//=============================================================================
|
|
// ISR Handler
|
|
//=============================================================================
|
|
__INTERRUPT void uart0_rx_handler(void)
|
|
{
|
|
SAVE_IRQ_CSR_CONTEXT();
|
|
|
|
if (UART_GetITStatus(UART0, UART_FLAG_RXNE))
|
|
{
|
|
char ch = (char)UART_ReceiveData(UART0);
|
|
|
|
if (ch == '\r' || ch == '\n')
|
|
{
|
|
if (g_uart_rx_idx > 0)
|
|
{
|
|
g_uart_rx_buf[g_uart_rx_idx] = '\0';
|
|
g_uart_rx_complete = true;
|
|
}
|
|
}
|
|
else if (g_uart_rx_idx < UART_CMD_RX_BUF_SIZE - 1)
|
|
{
|
|
g_uart_rx_buf[g_uart_rx_idx++] = ch;
|
|
}
|
|
}
|
|
|
|
RESTORE_IRQ_CSR_CONTEXT();
|
|
}
|
|
|
|
//=============================================================================
|
|
// Public Function Definition
|
|
//=============================================================================
|
|
void uart_cmd_init(void)
|
|
{
|
|
/* Configure PB3 as UART0 TX */
|
|
GPIO_InitTypeDef gpio_init = {0};
|
|
gpio_init.GPIO_Pin = UART_CMD_TX_PIN;
|
|
gpio_init.GPIO_Mode = GPIO_Mode_AF;
|
|
gpio_init.GPIO_AF_Mode = UART_CMD_TX_AF;
|
|
GPIO_Init(UART_CMD_TX_PORT, &gpio_init);
|
|
|
|
/* Configure PB5 as UART0 RX */
|
|
gpio_init.GPIO_Pin = UART_CMD_RX_PIN;
|
|
gpio_init.GPIO_Mode = GPIO_Mode_AF;
|
|
gpio_init.GPIO_AF_Mode = UART_CMD_RX_AF;
|
|
GPIO_Init(UART_CMD_RX_PORT, &gpio_init);
|
|
|
|
/* Configure UART0 */
|
|
UART_InitTypeDef uart_init = {0};
|
|
uart_init.BaudRate = UART_CMD_BAUD_RATE;
|
|
uart_init.WordLength = UART_WordLength_8b;
|
|
uart_init.StopBits = UART_StopBits_1;
|
|
uart_init.Parity = UART_Parity_No;
|
|
uart_init.Mode = UART_Mode_TxRx;
|
|
UART_Init(UART0, &uart_init);
|
|
|
|
/* Enable RX not-empty interrupt */
|
|
UART_ITConfig(UART0, UART_IT_RX_FIFO_NO_EMPTY, ENABLE);
|
|
|
|
/* Register UART0 IRQ */
|
|
sys_irq_attr_t irq_attr = {
|
|
.trig_mode = SYS_IRQ_TRIGGER_LEVEL,
|
|
.level = SYS_IRQ_LEVEL_H,
|
|
.priority = SYS_IRQ_PRIORITY_MIDDEN,
|
|
};
|
|
sys_register_IRQ(UART0_IRQn, uart0_rx_handler, &irq_attr);
|
|
|
|
/* Start UART */
|
|
UART_Start(UART0);
|
|
|
|
sys_enable_girq();
|
|
}
|
|
|
|
void uart_cmd_send_str(const char *str)
|
|
{
|
|
while (*str)
|
|
{
|
|
UART_SendData(UART0, *str++);
|
|
UART_WaitTxFifoEmpty(UART0);
|
|
}
|
|
}
|
|
|
|
void uart_cmd_process(void)
|
|
{
|
|
if (!g_uart_rx_complete)
|
|
return;
|
|
|
|
const char *arg = NULL;
|
|
|
|
if (cmd_strcmp(g_uart_rx_buf, "help") == 0)
|
|
{
|
|
uart_cmd_send_str("Commands:\r\n");
|
|
uart_cmd_send_str(" help - show this help\r\n");
|
|
uart_cmd_send_str(" fw_ver - show firmware version\r\n");
|
|
uart_cmd_send_str(" pwm 1/0 - enable/disable PWM output\r\n");
|
|
uart_cmd_send_str(" notify 1/0 - enable/disable notify\r\n");
|
|
}
|
|
else if (cmd_strcmp(g_uart_rx_buf, "fw_ver") == 0)
|
|
{
|
|
uart_cmd_send_str("FW: " FW_VERSION "\r\n");
|
|
}
|
|
else if (cmd_match_with_arg(g_uart_rx_buf, "pwm", &arg))
|
|
{
|
|
if (arg[0] == '1')
|
|
{
|
|
g_pwm_enabled = true;
|
|
uart_cmd_send_str("OK pwm on\r\n");
|
|
}
|
|
else if (arg[0] == '0')
|
|
{
|
|
g_pwm_enabled = false;
|
|
uart_cmd_send_str("OK pwm off\r\n");
|
|
}
|
|
else
|
|
{
|
|
uart_cmd_send_str("ERR usage: pwm 1/0\r\n");
|
|
}
|
|
}
|
|
else if (cmd_match_with_arg(g_uart_rx_buf, "notify", &arg))
|
|
{
|
|
if (arg[0] == '1')
|
|
{
|
|
g_notify_enabled = true;
|
|
uart_cmd_send_str("OK notify on\r\n");
|
|
}
|
|
else if (arg[0] == '0')
|
|
{
|
|
g_notify_enabled = false;
|
|
uart_cmd_send_str("OK notify off\r\n");
|
|
}
|
|
else
|
|
{
|
|
uart_cmd_send_str("ERR usage: notify 1/0\r\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uart_cmd_send_str("ERR unknown cmd\r\n");
|
|
}
|
|
|
|
/* Reset for next command */
|
|
g_uart_rx_idx = 0;
|
|
g_uart_rx_complete = false;
|
|
}
|