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.
153 lines
3.9 KiB
153 lines
3.9 KiB
|
22 hours ago
|
/*
|
||
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||
|
|
*
|
||
|
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
|
*
|
||
|
|
* Change Logs:
|
||
|
|
* Date Author Notes
|
||
|
|
* 2025-10-25 Administrator the first version
|
||
|
|
*/
|
||
|
|
# include <rtthread.h>
|
||
|
|
# include <rtdevice.h>
|
||
|
|
# include <board.h>
|
||
|
|
# include <stdio.h>
|
||
|
|
#include "uart_framework.h"
|
||
|
|
#include "data_comm.h"
|
||
|
|
|
||
|
|
#define LOG_TAG "uart.rx"
|
||
|
|
#define LOG_LVL LOG_LVL_DBG
|
||
|
|
//#include <ulog.h>
|
||
|
|
|
||
|
|
#define UART_NAME "uart2"
|
||
|
|
#define UART_BAUD_RATE BAUD_RATE_115200
|
||
|
|
|
||
|
|
#define RS485RD GET_PIN(A,10)
|
||
|
|
#define RS485_RX() rt_pin_write(RS485RD, 0)
|
||
|
|
#define RS485_TX() rt_pin_write(RS485RD, 1)
|
||
|
|
|
||
|
|
#define RECV_BUF_SIZE (512)
|
||
|
|
#define FRAME_TIMEOUT_MS 20
|
||
|
|
#define SEND_INTERVAL_MS 0
|
||
|
|
#define REQUEST_TIMEOUT_MS 250
|
||
|
|
|
||
|
|
static uart_framework_t uf = RT_NULL;
|
||
|
|
|
||
|
|
static void rs485_set_tx(void)
|
||
|
|
{
|
||
|
|
RS485_TX();
|
||
|
|
rt_thread_mdelay(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void rs485_set_rx(void)
|
||
|
|
{
|
||
|
|
rt_thread_mdelay(1);
|
||
|
|
RS485_RX();
|
||
|
|
}
|
||
|
|
|
||
|
|
static void rs485_gpio_init(void)
|
||
|
|
{
|
||
|
|
rt_pin_mode(RS485RD, PIN_MODE_OUTPUT);
|
||
|
|
rs485_set_rx();
|
||
|
|
}
|
||
|
|
|
||
|
|
static rt_err_t uart_rs485_init(void)
|
||
|
|
{
|
||
|
|
rt_device_t serial_device = rt_device_find(UART_NAME);
|
||
|
|
if (serial_device == RT_NULL)
|
||
|
|
{
|
||
|
|
rt_kprintf("not find the serial device:%s!", UART_NAME);
|
||
|
|
return -RT_ERROR;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 修改串口配置 */
|
||
|
|
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||
|
|
config.baud_rate = UART_BAUD_RATE;
|
||
|
|
config.bufsz = RECV_BUF_SIZE; // 接收缓冲区大小
|
||
|
|
rt_device_control(serial_device, RT_DEVICE_CTRL_CONFIG, &config);
|
||
|
|
|
||
|
|
rs485_gpio_init();
|
||
|
|
struct uart_framework_cfg cfg = { .uart_name = UART_NAME, .max_frame_size = RECV_BUF_SIZE, .frame_interval_ms =
|
||
|
|
FRAME_TIMEOUT_MS, .send_interval_ms = SEND_INTERVAL_MS, .rs485_txd = rs485_set_tx, .rs485_rxd = rs485_set_rx };
|
||
|
|
//如果不是485,则配置rs485_txd和rs485_rxd为RT_NULL
|
||
|
|
|
||
|
|
uf = uart_framework_create(&cfg);
|
||
|
|
if (uf == RT_NULL)
|
||
|
|
{
|
||
|
|
rt_kprintf("SCCM link create failed on %s\n", UART_NAME);
|
||
|
|
return -RT_ERROR;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
rt_kprintf("SCCM link create success on %s!\n", UART_NAME);
|
||
|
|
return RT_EOK;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static rt_err_t frame_handler(rt_uint8_t *data, rt_size_t size)
|
||
|
|
{
|
||
|
|
//解析数据
|
||
|
|
rt_err_t res;
|
||
|
|
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
|
||
|
|
if (!req){ return RT_ERROR;}
|
||
|
|
rt_strncpy(req->input, (const char *)data, sizeof(req->input));
|
||
|
|
req->input_len = size;
|
||
|
|
req->sem = rt_malloc(sizeof(struct rt_semaphore));
|
||
|
|
|
||
|
|
if (!req->sem) {
|
||
|
|
rt_free(req);
|
||
|
|
return RT_ERROR;
|
||
|
|
}
|
||
|
|
|
||
|
|
rt_sem_init(req->sem, "uart_resp", 0, RT_IPC_FLAG_FIFO);
|
||
|
|
|
||
|
|
// 发送到处理线程
|
||
|
|
if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK)
|
||
|
|
{
|
||
|
|
// 等待处理完成
|
||
|
|
if (rt_sem_take(req->sem, RT_WAITING_FOREVER) == RT_EOK)
|
||
|
|
{
|
||
|
|
res= uart_framework_send(uf, (rt_uint8_t *)req->output, req->output_len);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// 清理
|
||
|
|
rt_sem_detach(req->sem); // 或 rt_sem_delete
|
||
|
|
rt_free(req->sem);
|
||
|
|
rt_free(req);
|
||
|
|
|
||
|
|
//这里直接返回接收到的数据
|
||
|
|
// rt_uint8_t *frame_data = data;
|
||
|
|
// rt_uint16_t frame_len = size;
|
||
|
|
// rt_kprintf("rx_buf", 16, frame_data, frame_len);
|
||
|
|
// rt_err_t res = uart_framework_send(uf, frame_data, frame_len);
|
||
|
|
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void rs485_rx_handler(void *params)
|
||
|
|
{
|
||
|
|
while (1)
|
||
|
|
{
|
||
|
|
if(uart_framework_receive(uf, RT_WAITING_FOREVER, RT_NULL, RT_NULL, 0) == RT_EOK)
|
||
|
|
{
|
||
|
|
frame_handler(uf->rx_buf, uf->rx_size);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int app_uart_rs485_startup(void)
|
||
|
|
{
|
||
|
|
rt_err_t rst;
|
||
|
|
rst = uart_rs485_init();
|
||
|
|
if (rst != RT_EOK)
|
||
|
|
return rst;
|
||
|
|
|
||
|
|
rt_thread_t t = rt_thread_create("rs485rx", rs485_rx_handler, RT_NULL, 1024 * 4, 12, 20);
|
||
|
|
if (t == RT_NULL)
|
||
|
|
return -RT_ENOMEM;
|
||
|
|
|
||
|
|
rst = rt_thread_startup(t);
|
||
|
|
|
||
|
|
return rst;
|
||
|
|
}
|
||
|
|
//INIT_APP_EXPORT(app_uart_rs485_startup);
|