EV-Embedded-Control-System/middlewares/FreeModbus/port/FreeRTOS/portserial.c

310 lines
8.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* FreeModbus Libary: RT-Thread Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: portserial.c,v 1.60 2013/08/13 15:07:05 Armink $
*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
static usart_type* port_uart_list[] = {UART5, UART7};
static usart_type* port_uart;
/* ----------------------- Static variables ---------------------------------*/
/* software simulation serial transmit IRQ handler thread */
static TaskHandle_t thread_serial_soft_trans_irq = NULL;
/* serial event */
static EventGroupHandle_t event_serial;
/* modbus slave serial device */
//static UART_HandleTypeDef *serial;
/*
* Serial FIFO mode
*/
static volatile uint8_t rx_buff[FIFO_SIZE_MAX];
static Serial_fifo Slave_serial_rx_fifo;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1 << 0)
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
static void serial_soft_trans_irq(void *parameter);
//static void Slave_TxCpltCallback(struct __UART_HandleTypeDef *huart);
//static void Slave_RxCpltCallback(struct __UART_HandleTypeDef *huart);
static int stm32_getc(void);
static int stm32_putc(CHAR c);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
eMBParity eParity) {
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
*/
BOOL bStatus = FALSE;
usart_parity_selection_type usart_parity;
usart_stop_bit_num_type usart_stop;
usart_data_bit_num_type usart_data;
gpio_init_type gpio_init_struct;
bStatus = TRUE;
if(ucPORT < (sizeof(port_uart_list) / sizeof(usart_type*)))
{
port_uart = port_uart_list[ucPORT];
}
else
{
bStatus = FALSE;
}
switch ( eParity )
{
case MB_PAR_NONE:
usart_parity = USART_PARITY_NONE;
usart_stop = USART_STOP_2_BIT;
break;
case MB_PAR_ODD:
usart_parity = USART_PARITY_ODD;
usart_stop = USART_STOP_1_BIT;
break;
case MB_PAR_EVEN:
usart_parity = USART_PARITY_EVEN;
usart_stop = USART_STOP_1_BIT;
break;
default:
bStatus = FALSE;
break;
}
switch ( ucDataBits )
{
case 8:
if(usart_stop == USART_STOP_1_BIT)
{
usart_data = USART_DATA_9BITS;
}
else if(usart_stop == USART_STOP_2_BIT)
{
usart_data = USART_DATA_8BITS;
}
else
{
bStatus = FALSE;
}
break;
case 7:
if(usart_stop == USART_STOP_1_BIT)
{
usart_data = USART_DATA_8BITS;
}
else if(usart_stop == USART_STOP_2_BIT)
{
usart_data = USART_DATA_8BITS; //before F435 not support 7bit.
}
else
{
bStatus = FALSE;
}
break;
default:
bStatus = FALSE;
break;
}
/* configure uart param */
usart_parity_selection_config(port_uart, usart_parity);
usart_init(port_uart, ulBaudRate, usart_data, usart_stop);
// usart_rs485_delay_time_config(port_uart, 2, 2);
// usart_de_polarity_set(port_uart, USART_DE_POLARITY_HIGH);
// usart_rs485_mode_enable(port_uart, TRUE);
usart_transmitter_enable(port_uart, TRUE);
usart_receiver_enable(port_uart, TRUE);
usart_enable(port_uart, TRUE);
NVIC_ClearPendingIRQ(UART5_IRQn);
nvic_irq_enable(UART5_IRQn, 0, 1);
/* software initialize */
Slave_serial_rx_fifo.buffer = rx_buff;
Slave_serial_rx_fifo.get_index = 0;
Slave_serial_rx_fifo.put_index = 0;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD><EFBFBD>߳<EFBFBD>*/
event_serial = xEventGroupCreate(); //<2F><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
if (NULL != event_serial) {
MODBUS_DEBUG("Create Slave event_serial Event success!\r\n");
} else {
MODBUS_DEBUG("Create Slave event_serial Event Faild!\r\n");
}
BaseType_t xReturn =
xTaskCreate((TaskFunction_t)serial_soft_trans_irq, /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
(const char *)"slave trans", /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
(uint16_t)128, /* ջ*/
(void *)NULL, /* <20><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD> */
(UBaseType_t)12, /* <20><><EFBFBD>ȼ<EFBFBD>*/
(TaskHandle_t *)&thread_serial_soft_trans_irq); /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
if (xReturn == pdPASS) {
MODBUS_DEBUG("xTaskCreate slave trans success\r\n");
}
return TRUE;
}
void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable) {
// __HAL_UART_CLEAR_FLAG(serial,UART_FLAG_RXNE);
// __HAL_UART_CLEAR_FLAG(serial,UART_FLAG_TC);
// if (xRxEnable) {
// /* enable RX interrupt */
// __HAL_UART_ENABLE_IT(serial, UART_IT_RXNE);
// /* switch 485 to receive mode */
// MODBUS_DEBUG("RS485_RX_MODE\r\n");
// SLAVE_RS485_RX_MODE;
// } else {
// /* switch 485 to transmit mode */
// MODBUS_DEBUG("RS485_TX_MODE\r\n");
// SLAVE_RS485_TX_MODE;
// /* disable RX interrupt */
// __HAL_UART_DISABLE_IT(serial, UART_IT_RXNE);
// }
if(xRxEnable == TRUE)
{
usart_interrupt_enable(port_uart, USART_RDBF_INT, TRUE);
}
else
{
usart_interrupt_enable(port_uart, USART_RDBF_INT, FALSE);
}
//不使用发送中断
// if(xTxEnable == TRUE)
// {
// usart_interrupt_enable(port_uart, USART_TDBE_INT, TRUE);
// }
// else
// {
// usart_interrupt_enable(port_uart, USART_TDBE_INT, FALSE);
// }
if (xTxEnable) {
/* start serial transmit */
xEventGroupSetBits(event_serial, EVENT_SERIAL_TRANS_START);
} else {
/* stop serial transmit */
xEventGroupClearBits(event_serial, EVENT_SERIAL_TRANS_START);
/*<2A><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>*/
// printf("ms=%.2f,fps=%.2f\r\n", __HAL_TIM_GetCounter(&htim7) / 100.f,
// 1000.f / (__HAL_TIM_GetCounter(&htim7) / 100.f));
}
}
void vMBPortClose(void)
{
}
/*Send a byte*/
BOOL xMBPortSerialPutByte(CHAR ucByte) {
stm32_putc(ucByte);
return TRUE;
}
/*Get a byte from fifo*/
BOOL xMBPortSerialGetByte(CHAR *pucByte) {
Get_from_fifo(&Slave_serial_rx_fifo, (uint8_t *)pucByte, 1);
return TRUE;
}
/*
* Create an interrupt handler for the transmit buffer empty interrupt
* (or an equivalent) for your target processor. This function should then
* call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
* a new character can be sent. The protocol stack will then call
* xMBPortSerialPutByte( ) to send the character.
*/
void prvvUARTTxReadyISR(void) { pxMBFrameCBTransmitterEmpty(); }
/*
* Create an interrupt handler for the receive interrupt for your target
* processor. This function should then call pxMBFrameCBByteReceived( ). The
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
void prvvUARTRxISR(void) { pxMBFrameCBByteReceived(); }
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static void serial_soft_trans_irq(void *parameter) {
uint32_t recved_event;
while (1) {
/* waiting for serial transmit start */
xEventGroupWaitBits(event_serial, /* <20>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
EVENT_SERIAL_TRANS_START, /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4><EFBFBD>¼<EFBFBD> */
pdFALSE, /* <20>˳<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>?? */
pdFALSE, /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?? */
portMAX_DELAY); /* ָ<><D6B8><EFBFBD><EFBFBD>ʱ<EFBFBD>¼<EFBFBD>,<2C><><EFBFBD>޵ȴ<DEB5> */
/* execute modbus callback */
prvvUARTTxReadyISR();
}
}
/*UART<52><54><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>*/
static int stm32_putc(CHAR c) {
// serial->Instance->DR = c;
// while (!(serial->Instance->SR & UART_FLAG_TC))
// ;
usart_data_transmit(port_uart, c);
return TRUE;
}
void vUSARTHandler( void )
{
int ch = -1;
if(port_uart->ctrl1_bit.rdbfien == SET)
{
if(usart_flag_get(port_uart, USART_RDBF_FLAG) == SET)
{
ch = usart_data_receive(port_uart);
Put_in_fifo(&Slave_serial_rx_fifo, (uint8_t *)&ch, 1);
prvvUARTRxISR();
}
}
if(port_uart->ctrl1_bit.tdbeien == SET)
{
if(usart_flag_get(port_uart, USART_TDBE_FLAG) == SET)
{
prvvUARTTxReadyISR();
}
}
}
//void UART7_IRQHandler(void)
//{
// vUSARTHandler( );
//}