EV-Embedded-Control-System/middlewares/libmodbus/uart_device.c

262 lines
5.8 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-3.0-only
/*
* Copyright (c) 2008-2023 100askTeam : Dongshan WEI <weidongshan@qq.com>
* Discourse: https://forums.100ask.net
*/
/* Copyright (C) 2008-2023 深圳百问网科技有限公司
* All rights reserved
*
* : , 使, (),
* : , ,
*
* GPL V3协议,
* : https://www.100ask.net
* : https://forums.100ask.net
* B站 : https://space.bilibili.com/275908810
* : DShanMCU-F103
* : https://100ask.taobao.com
* (E-mail): weidongshan@qq.com
*
*
*
*
*-----------------------------------------------------
* 2024.02.01 v01
*-----------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
//#include "cmsis_os.h"
#include "semphr.h"
#include "queue.h"
#include "uart_device.h"
#include "wk_bsp.h"
#define UART_RECV_BUF 128
#define LIB_MB_UART UART5
typedef struct UART_Data {
// UART_HandleTypeDef *huart;
usart_type *usart_x;
uint8_t recv_char;
SemaphoreHandle_t xSendSemaphore;
QueueHandle_t xRecvQueue;
}UART_Data, *P_UART_Data;
static UART_Data g_uart2_data = {
// &huart2,
LIB_MB_UART,
};
void HAL_UART_TxCpltCallback(usart_type *huart)
{
/* 释放信号量 */
P_UART_Data pData;
/* 把数据放入队列 */
if (huart == LIB_MB_UART)
{
pData = &g_uart2_data;
xSemaphoreGiveFromISR(pData->xSendSemaphore, NULL);
}
}
//数据接收中断
void HAL_UART_RxCpltCallback(usart_type *huart)
{
P_UART_Data pData;
/* 把数据放入队列 */
if (huart == LIB_MB_UART)
{
pData = &g_uart2_data;
pData->recv_char = usart_data_receive(pData->usart_x);
xQueueSendFromISR(pData->xRecvQueue, &pData->recv_char, NULL);
/* re-enable rxne interrupt */
// HAL_UART_Receive_IT(pData->huart, &pData->recv_char, 1);
}
}
int uart_init( struct UART_Device *pDev, int baud, char parity, int data_bit, int stop_bit)
{
P_UART_Data pData = pDev->priv_data;
uint8_t bStatus = FALSE;
usart_parity_selection_type usart_parity;
usart_stop_bit_num_type usart_stop;
usart_data_bit_num_type usart_data;
bStatus = TRUE;
switch ( parity )
{
case 'N':
usart_parity = USART_PARITY_NONE;
usart_stop = USART_STOP_1_BIT;
usart_data = USART_DATA_8BITS;
break;
case 'O':
usart_parity = USART_PARITY_ODD;
usart_stop = USART_STOP_1_BIT;
usart_data = USART_DATA_9BITS;
break;
case 'E':
usart_parity = USART_PARITY_EVEN;
usart_stop = USART_STOP_1_BIT;
usart_data = USART_DATA_9BITS;
break;
default:
bStatus = FALSE;
break;
}
// switch ( data_bit )
// {
// case 8:
// if(usart_stop == USART_STOP_1_BIT)
// {
// usart_data = USART_DATA_8BITS;
// }
// else
// {
// bStatus = FALSE;
// }
// break;
// default:
// bStatus = FALSE;
// break;
// }
//串口初始化
if(TRUE == bStatus)
{
wk_uart5_init(baud, usart_data, usart_stop, usart_parity);
NVIC_ClearPendingIRQ(UART5_IRQn);
nvic_irq_enable(UART5_IRQn, 7, 0); //emac = 5
if (!pData->xSendSemaphore)
{
pData->xSendSemaphore = xSemaphoreCreateBinary( );
pData->xRecvQueue = xQueueCreate(UART_RECV_BUF, 1);
}
/* 使能接收中断 */
/* enable rxne interrupt */
// HAL_UART_Receive_IT(pData->huart, &pData->recv_char, 1);
usart_interrupt_enable(pData->usart_x, USART_RDBF_INT, TRUE);
}
return 0;
}
int uart_send( struct UART_Device *pDev, uint8_t *datas, uint32_t len, int timeout)
{
P_UART_Data pData = pDev->priv_data;
//
// RTT_LOG("%x, %d", *datas, len);
for(uint8_t i = 0; i < len; i++)
{
while(usart_flag_get(pData->usart_x, USART_TDBE_FLAG) == RESET);
usart_data_transmit(pData->usart_x, *datas);
while(usart_flag_get(pData->usart_x, USART_TDC_FLAG) == RESET)
{
};
datas++;
}
// if (HAL_OK == HAL_UART_Transmit_IT(pData->huart, datas, len)) /* 触发"发送空中断",并不表示数据已经发送完毕 */
// {
/* 等待信号量 */
// if (pdTRUE == xSemaphoreTake(pData->xSendSemaphore, timeout))
return 0;
// else
// return -1;
// }
// else
// return -1;
}
int uart_recv( struct UART_Device *pDev, uint8_t *data, int timeout)
{
P_UART_Data pData = pDev->priv_data;
/* 读队列 */
if (pdPASS == xQueueReceive(pData->xRecvQueue, data, timeout))
{
// RTT_LOG("%02x ", *data);
return 0;
}
else
return -1;
}
int uart_flush(struct UART_Device *pDev)
{
P_UART_Data pData = pDev->priv_data;
uint8_t data;
int i = 0;
/* 读队列 */
while (pdPASS == xQueueReceive(pData->xRecvQueue, &data, 0))
{
i++;
}
// RTT_LOG("%02x ", data);
return i;
}
static struct UART_Device g_uart5_dev = {"uart5", uart_init, uart_send, uart_recv, uart_flush, &g_uart2_data};
static struct UART_Device *g_uart_devices[] = {&g_uart5_dev};
struct UART_Device *GetUARTDevice(char *name)
{
int i = 0;
for (i = 0; i < sizeof(g_uart_devices)/sizeof(g_uart_devices[0]); i++)
{
if (!strcmp(name, g_uart_devices[i]->name))
return g_uart_devices[i];
}
return NULL;
}
void UART5_IRQHandler(void)
{
static usart_type* port_uart;
port_uart = LIB_MB_UART;
if(port_uart->ctrl1_bit.rdbfien == SET)
{
if(usart_flag_get(port_uart, USART_RDBF_FLAG) == SET)
{
HAL_UART_RxCpltCallback(LIB_MB_UART);
}
}
}