455 lines
11 KiB
C
455 lines
11 KiB
C
#include "board.h"
|
||
#include "motor.h"
|
||
|
||
void motor_process(frame_msg_t *rx, frame_msg_t *bk);
|
||
void sensor_process(frame_msg_t *rx, frame_msg_t *bk);
|
||
void error_process(uint8_t err, frame_msg_t *rx, frame_msg_t *bk);
|
||
|
||
/************************************* 串口通讯 *************************************/
|
||
uart_t *uarts[UART_NUM_MAX];
|
||
__IO static BOOL execute_state = IDLE; // 数据处理标志
|
||
static frame_msg_t rx_msg; // 接收数据句柄
|
||
static frame_msg_t bk_msg; // 回复数据句柄
|
||
static uint8_t host_send_buffer[UART_TXSIZE] = {0}; // 数据发送缓存
|
||
|
||
// 串口发送
|
||
static void host_send_msg(uint8_t *data, uint16_t len)
|
||
{
|
||
uart_send_data(uarts[UART_NUM_1], data, len);
|
||
}
|
||
|
||
// 数据有效性检查
|
||
static BOOL host_data_verify(uint8_t *data, uint16_t len)
|
||
{
|
||
BOOL ret = TRUE;
|
||
uint8_t ver_len = 0;
|
||
uint8_t msg_crc = 0, ver_crc = 0;
|
||
|
||
// 包头包尾检查
|
||
if (data[0] != PACKET_STX || data[1] != ST_DEV_NORMAL || data[len - 1] != PACKET_ETX)
|
||
{
|
||
ret = FALSE;
|
||
return ret;
|
||
}
|
||
// 长度检查
|
||
ver_len = PACKET_MIN_LEN + data[DATA_LEN_INDEX];
|
||
if (ver_len != len)
|
||
{
|
||
ret = FALSE;
|
||
return ret;
|
||
}
|
||
// CRC校验
|
||
msg_crc = data[len - 2];
|
||
ver_crc = xor_compute((uint8_t *)&data[1], (len - 3)); // 减去包头、包尾、校验
|
||
if (msg_crc != ver_crc)
|
||
{
|
||
ret = FALSE;
|
||
return ret;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 数据解码
|
||
static void host_data_decode(uint8_t *data, uint16_t len)
|
||
{
|
||
DBG_ASSERT(data != NULL __DBG_LINE);
|
||
|
||
// 获取数据长度和消息长度
|
||
uint8_t data_len = data[DATA_LEN_INDEX];
|
||
uint8_t msg_len = DATA_INDEX + data_len;
|
||
// 获取消息数据
|
||
osel_memcpy((uint8_t *)&rx_msg, data, msg_len);
|
||
}
|
||
|
||
// 指令执行
|
||
static void host_cmd_execute(frame_msg_t *rx_msg, frame_msg_t *bk_msg)
|
||
{
|
||
DBG_ASSERT(rx_msg != NULL __DBG_LINE);
|
||
DBG_ASSERT(bk_msg != NULL __DBG_LINE);
|
||
|
||
switch (rx_msg->dev_no)
|
||
{
|
||
case ADC_SENSOR:
|
||
sensor_process(rx_msg, bk_msg);
|
||
break;
|
||
case MOTOR:
|
||
motor_process(rx_msg, bk_msg);
|
||
break;
|
||
default:
|
||
error_process(ST_CMD_IVALID, rx_msg, bk_msg);
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 数据编码
|
||
static void host_data_encode(frame_msg_t *msg)
|
||
{
|
||
DBG_ASSERT(msg != NULL __DBG_LINE);
|
||
|
||
uint8_t *pbuf = (uint8_t *)host_send_buffer;
|
||
uint8_t index = 0, len = 0;
|
||
|
||
// 消息数据
|
||
uint8_t msg_len = DATA_INDEX + msg->len;
|
||
osel_memcpy(pbuf, (uint8_t *)msg, msg_len);
|
||
// 校验码
|
||
index += msg_len;
|
||
pbuf[index] = xor_compute((uint8_t *)&pbuf[1], (msg_len - 1)); // 减去包头
|
||
// 包尾
|
||
index += 1;
|
||
pbuf[index] = PACKET_ETX;
|
||
|
||
// 计算报文长度
|
||
len = msg_len + 2; // 加上校验、包尾
|
||
// 发送
|
||
host_send_msg(pbuf, len);
|
||
}
|
||
|
||
// 数据处理
|
||
void host_rx_msg_deal(void)
|
||
{
|
||
if (execute_state == IDLE)
|
||
{
|
||
return;
|
||
}
|
||
|
||
frame_msg_t *p_rx_msg = (frame_msg_t *)&rx_msg;
|
||
frame_msg_t *p_bk_msg = (frame_msg_t *)&bk_msg;
|
||
|
||
// 执行
|
||
host_cmd_execute(p_rx_msg, p_bk_msg);
|
||
// 回复(组包 + 发送)
|
||
host_data_encode(p_bk_msg);
|
||
// 复位
|
||
osel_memset((uint8_t *)host_send_buffer, 0, UART_TXSIZE);
|
||
osel_memset((uint8_t *)&rx_msg, 0, sizeof(frame_msg_t));
|
||
osel_memset((uint8_t *)&bk_msg, 0, sizeof(frame_msg_t));
|
||
execute_state = IDLE;
|
||
}
|
||
|
||
// 串口接收回调
|
||
static void host_rx_cb(uint8_t uart_index, uint8_t *data, uint16_t len)
|
||
{
|
||
BOOL ret = FALSE;
|
||
|
||
// 数据有效性检查
|
||
ret = host_data_verify(data, len);
|
||
// 数据解码
|
||
if (ret == TRUE && execute_state == IDLE)
|
||
{
|
||
host_data_decode(data, len);
|
||
execute_state = BUSY;
|
||
}
|
||
}
|
||
|
||
// 串口初始化
|
||
static void host_uart_init(void)
|
||
{
|
||
if (uarts[UART_NUM_1] == NULL)
|
||
{
|
||
uarts[UART_NUM_1] = uart_create(USART1, TRUE, UART_RXSIZE, host_rx_cb, TRUE, UART_TXSIZE, NULL);
|
||
uarts[UART_NUM_1]->uart_index = UART_NUM_1;
|
||
uarts[UART_NUM_1]->dma = DMA1;
|
||
uarts[UART_NUM_1]->dma_rx_channel = LL_DMA_CHANNEL_3;
|
||
uarts[UART_NUM_1]->dma_tx_channel = LL_DMA_CHANNEL_2;
|
||
uart_recv_en(uarts[UART_NUM_1]);
|
||
}
|
||
}
|
||
|
||
/************************************* 电机 *************************************/
|
||
// 电机对象
|
||
motor_t *motor;
|
||
motor_ctrl_t *motor_param = NULL;
|
||
|
||
extern uint8_t detect_result;
|
||
|
||
// 电机初始化
|
||
static void motor_init(void)
|
||
{
|
||
motor = motor_create(STEP_MOTOR);
|
||
gpio_t dir = {
|
||
.port = DIR_GPIO_Port,
|
||
.pin = DIR_Pin,
|
||
};
|
||
gpio_t en = {
|
||
.port = ENA_GPIO_Port,
|
||
.pin = ENA_Pin,
|
||
};
|
||
motor->handle.step_motor.interface.init(motor, dir, en, MIN_STEP_ANGLE, TIM21, LL_TIM_CHANNEL_CH2);
|
||
}
|
||
|
||
static uint8_t motor_param_get(frame_msg_t *rx, motor_ctrl_t *param)
|
||
{
|
||
uint8_t state = ST_DEV_NORMAL;
|
||
|
||
// 检查数据长度,方向:1个字节,角度:4个字节
|
||
if (rx->len < 5)
|
||
{
|
||
state = ST_CMD_IVALID;
|
||
return state;
|
||
}
|
||
// 方向
|
||
param->dir = rx->data[0];
|
||
// 角度
|
||
osel_memcpy((uint8_t *)¶m->angle, (uint8_t *)&rx->data[1], 4);
|
||
param->angle = B2S_FLOAT32(param->angle);
|
||
|
||
return state;
|
||
}
|
||
|
||
static uint8_t motor_ctrl(uint8_t sw, motor_ctrl_t *param)
|
||
{
|
||
step_motor_t *step_motor = &motor->handle.step_motor;
|
||
uint8_t state = detect_result;
|
||
if (sw == RUN && detect_result == ST_DEV_NORMAL)
|
||
{
|
||
step_motor->interface.set_angle(motor, param->angle, (dir_e)param->dir);
|
||
}
|
||
else
|
||
{
|
||
step_motor->interface.stop(motor);
|
||
}
|
||
return state;
|
||
}
|
||
|
||
void motor_process_init(void)
|
||
{
|
||
motor_param = (motor_ctrl_t *)osel_mem_alloc(sizeof(motor_ctrl_t));
|
||
DBG_ASSERT(motor_param != NULL __DBG_LINE);
|
||
osel_memset((uint8_t *)motor_param, 0, sizeof(motor_ctrl_t));
|
||
}
|
||
|
||
// 电机任务
|
||
void motor_process(frame_msg_t *rx, frame_msg_t *bk)
|
||
{
|
||
DBG_ASSERT(rx != NULL __DBG_LINE);
|
||
DBG_ASSERT(bk != NULL __DBG_LINE);
|
||
|
||
motor_ctrl_t *ctrl_param = motor_param;
|
||
uint8_t state = ST_DEV_NORMAL;
|
||
|
||
switch (rx->cmd_no)
|
||
{
|
||
case SET_MOTOR_SPEED: // 设置电机转速
|
||
break;
|
||
case MOTOR_MOVE: // 运行电机
|
||
{
|
||
// 读取参数
|
||
state = motor_param_get(rx, ctrl_param);
|
||
// 运行电机
|
||
if (state == ST_DEV_NORMAL)
|
||
{
|
||
state = motor_ctrl(RUN, ctrl_param);
|
||
}
|
||
// 回复数据
|
||
osel_memcpy((uint8_t *)bk, (uint8_t *)rx, sizeof(frame_msg_t));
|
||
bk->state = state;
|
||
break;
|
||
}
|
||
case MOTOR_STOP: // 停止电机
|
||
{
|
||
// 停止电机
|
||
state = motor_ctrl(STOP, ctrl_param);
|
||
// 回复数据
|
||
osel_memcpy((uint8_t *)bk, (uint8_t *)rx, sizeof(frame_msg_t));
|
||
bk->state = state;
|
||
break;
|
||
}
|
||
default:
|
||
error_process(ST_CMD_IVALID, rx, bk);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/************************************* ADc传感器 *************************************/
|
||
uint16_t sensor_adc[GET_ALL_VALUE] = {0};
|
||
|
||
// AD传感器
|
||
adc_t adc1 = {
|
||
.adc = ADC1,
|
||
.dma = DMA1,
|
||
.dma_channel = LL_DMA_CHANNEL_1,
|
||
};
|
||
|
||
// 扭力,单位:N·m
|
||
uint16_t get_torsion_adc(void)
|
||
{
|
||
uint16_t adc = adc_get_result_average(IN13);
|
||
return adc;
|
||
}
|
||
|
||
float32 torsion_detect(void)
|
||
{
|
||
float32 adc = 0.0, val = 0.0;
|
||
|
||
adc = get_torsion_adc();
|
||
val = adc / 4096 * 3000;
|
||
val = (val - 1500) / 101 / (1.934 * 3) * 10;
|
||
|
||
return val;
|
||
}
|
||
|
||
// 压力,单位:kPa
|
||
uint16_t get_pressure_adc(void)
|
||
{
|
||
uint16_t adc = adc_get_result_average(IN7);
|
||
return adc;
|
||
}
|
||
|
||
float32 pressure_detect(void)
|
||
{
|
||
float32 adc = 0.0, val = 0.0;
|
||
|
||
adc = get_pressure_adc();
|
||
val = adc / 4096 * 3000;
|
||
val = (val - 600) / (10 * 15) / 16 * 1000;
|
||
|
||
return val;
|
||
}
|
||
|
||
// 流量,单位:SLPM
|
||
uint16_t get_flow_adc(void)
|
||
{
|
||
uint16_t adc = adc_get_result_average(IN8);
|
||
return adc;
|
||
}
|
||
|
||
float32 flow_detect(void)
|
||
{
|
||
float32 adc = 0.0, val = 0.0;
|
||
|
||
adc = get_flow_adc();
|
||
val = adc / 4096 * 3000;
|
||
val = (val - 600) / (10 * 15) / 16 * 300;
|
||
|
||
return val;
|
||
}
|
||
|
||
// 传感器任务
|
||
void sensor_process(frame_msg_t *rx, frame_msg_t *bk)
|
||
{
|
||
DBG_ASSERT(rx != NULL __DBG_LINE);
|
||
DBG_ASSERT(bk != NULL __DBG_LINE);
|
||
|
||
uint8_t state = ST_DEV_NORMAL;
|
||
|
||
// 检查指令合法性
|
||
if (rx->cmd_no > GET_ALL_VALUE)
|
||
{
|
||
state = ST_CMD_IVALID;
|
||
goto encode;
|
||
}
|
||
|
||
encode:
|
||
// 回复数据
|
||
bk->head = PACKET_STX;
|
||
bk->state = state;
|
||
bk->dev_no = rx->dev_no;
|
||
bk->cmd_no = rx->cmd_no;
|
||
if (rx->cmd_no >= GET_ALL_VALUE)
|
||
{
|
||
bk->len = sizeof(uint16_t) * GET_ALL_VALUE;
|
||
osel_memcpy((uint8_t *)bk->data, (uint8_t *)&sensor_adc, bk->len);
|
||
}
|
||
else
|
||
{
|
||
bk->len = sizeof(uint16_t);
|
||
osel_memcpy((uint8_t *)bk->data, (uint8_t *)&sensor_adc[bk->cmd_no], bk->len);
|
||
}
|
||
}
|
||
|
||
/************************************* 测试 *************************************/
|
||
#if SELF_TEST
|
||
test_t self_test = {TEST_DEV_IDEL, 0};
|
||
uint8_t test_buffer[UART_RXSIZE] = {0}; // 数据接收缓存
|
||
#endif
|
||
|
||
// 传感器测试指令
|
||
static uint8_t test_sensor_cmd(uint8_t cmd, uint8_t *buf)
|
||
{
|
||
uint8_t ver_len = 0;
|
||
uint8_t index = 0;
|
||
frame_msg_t msg;
|
||
msg.head = PACKET_STX;
|
||
msg.state = ST_DEV_NORMAL;
|
||
msg.dev_no = ADC_SENSOR;
|
||
msg.cmd_no = cmd;
|
||
msg.len = 0;
|
||
|
||
index = DATA_INDEX;
|
||
osel_memset(buf, 0, UART_RXSIZE);
|
||
osel_memcpy(buf, (uint8_t *)&msg, index);
|
||
buf[index] = xor_compute((uint8_t *)&buf[1], (index - 1));
|
||
index += 1;
|
||
buf[index] = PACKET_ETX;
|
||
index += 1;
|
||
|
||
ver_len = index;
|
||
return ver_len;
|
||
}
|
||
|
||
// 发送测试数据
|
||
static void test_rx_cb(uint8_t *data, uint8_t len)
|
||
{
|
||
BOOL ret = FALSE;
|
||
|
||
// 数据有效性检查
|
||
ret = host_data_verify(data, len);
|
||
// 数据解码
|
||
if (ret == TRUE && execute_state == IDLE)
|
||
{
|
||
host_data_decode(data, len);
|
||
execute_state = BUSY;
|
||
}
|
||
}
|
||
|
||
// 测试任务
|
||
void test_process(void)
|
||
{
|
||
uint8_t len = 0;
|
||
uint8_t *buf = test_buffer;
|
||
|
||
if (self_test.dev_id >= TEST_DEV_MAX)
|
||
{
|
||
return;
|
||
}
|
||
|
||
switch (self_test.dev_id)
|
||
{
|
||
case TEST_DEV_SENSOR:
|
||
len = test_sensor_cmd(self_test.cmd_id, buf);
|
||
break;
|
||
case TEST_DEV_MOTOR:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
test_rx_cb(buf, len);
|
||
self_test.dev_id = TEST_DEV_IDEL;
|
||
}
|
||
|
||
/************************************* 板卡 *************************************/
|
||
// 板卡初始化
|
||
void board_init(void)
|
||
{
|
||
motor = NULL;
|
||
my_mem_init(SRAMIN);
|
||
|
||
motor_init(); // 电机初始化
|
||
adc_init(adc1); // 初始化ADC1通道,默认采集AD
|
||
host_uart_init(); // 串口初始化
|
||
ENABLE_TIM(TIM6); // 任务流程定时器使能
|
||
}
|
||
|
||
// 不支持的任务
|
||
void error_process(uint8_t err, frame_msg_t *rx, frame_msg_t *bk)
|
||
{
|
||
DBG_ASSERT(rx != NULL __DBG_LINE);
|
||
DBG_ASSERT(bk != NULL __DBG_LINE);
|
||
|
||
osel_memcpy((uint8_t *)bk, (uint8_t *)rx, sizeof(frame_msg_t));
|
||
bk->state = err;
|
||
}
|