RS485 UART переделал на DMA по образцу HVD4

This commit is contained in:
Alexander Kurmis
2022-10-19 23:51:50 +03:00
parent e226faa454
commit 3803869521
12 changed files with 191 additions and 200 deletions

View File

@@ -6,11 +6,13 @@
#include <stdint.h>
#include "main.h"
#include "uart.h"
#include "modbus_logic.h"
volatile uint8_t recv_buffer[BUFFERS_SIZE];
volatile uint8_t send_buffer[BUFFERS_SIZE];
extern UART_HandleTypeDef huart1;
extern DMA_HandleTypeDef hdma_usart1_rx;
uint8_t recv_buffer[BUFFERS_SIZE];
uint8_t send_buffer[BUFFERS_SIZE];
uint16_t bytes_to_send = 0;
uint16_t last_rx_time = 0xFFFF;
@@ -19,55 +21,56 @@ enum send_state cmd_sending = SEND_IDLE;
uint16_t tranfer_errors_count;
extern uint16_t led_time_act;
static void process_incoming_packet();
void process_incoming_packet();
void UART_RxCpltCallback(void)
#define TXEN_ON HAL_GPIO_WritePin(TXEN_GPIO_Port, TXEN_Pin, GPIO_PIN_SET)
#define TXEN_OFF HAL_GPIO_WritePin(TXEN_GPIO_Port, TXEN_Pin, GPIO_PIN_RESET)
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
uint16_t pdu_size;
uint16_t remaining_size;
if (cmd_receiving == RECV_READ_HEADER)
{
// Check destination address
if (recv_buffer[5] != BOARD_ADRESS)
{
cmd_receiving = RECV_ERROR;
return;
}
// Check function code
if (recv_buffer[6] == 3 || recv_buffer[6] == 4 || recv_buffer[6] == 6)
{
cmd_receiving = RECV_READ_COMPLETE;
return;
}
else if (recv_buffer[6] == 0x10)
{
cmd_receiving = RECV_READ_DATA;
pdu_size = *((uint16_t*)(recv_buffer + 2));
// Receive remaining PDU and checksum
remaining_size = pdu_size - (MODBUS_HEADER_SIZE - 4) + 2;
if (remaining_size + MODBUS_HEADER_SIZE <= BUFFERS_SIZE)
UART_Receive_IT(recv_buffer + MODBUS_HEADER_SIZE, remaining_size, 5000);
if (huart->Instance == USART1)
{
if (recv_buffer[5] != BOARD_ADRESS)
{
cmd_receiving = RECV_ERROR;
return;
}
// Check function code
if (recv_buffer[6] == 3 || recv_buffer[6] == 4 || recv_buffer[6] == 6)
{
if(Size==MODBUS_HEADER_SIZE)cmd_receiving = RECV_READ_COMPLETE;
return;
}
else if (recv_buffer[6] == 0x10)
{
uint16_t pdu_size = *((uint16_t*)(recv_buffer + 2));
uint16_t remaining_size = pdu_size - (MODBUS_HEADER_SIZE - 4) + 2;
if (remaining_size + MODBUS_HEADER_SIZE == Size)
cmd_receiving = RECV_READ_COMPLETE;
else
{
cmd_receiving = RECV_ERROR;
tranfer_errors_count++;
}
return;
}
else
{
tranfer_errors_count++;
return;
}
else
{
tranfer_errors_count++;
cmd_receiving = RECV_ERROR;
return;
}
}
else if (cmd_receiving == RECV_READ_DATA)
{
cmd_receiving = RECV_READ_COMPLETE;
}
cmd_receiving = RECV_ERROR;
return;
}
}
}
void UART_TxCpltCallback()
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
cmd_sending = SEND_IDLE;
if (huart->Instance == USART1)
{
cmd_sending = SEND_IDLE;
TXEN_OFF;
}
}
void modbus_loop_iterate()
@@ -76,19 +79,22 @@ void modbus_loop_iterate()
{
if (cmd_receiving == RECV_ERROR)
{
//delay_ms(30); // poor man's way to synchronize packets
if(last_rx_time>=BUS_IDLE_TIME)
{
// poor man's way to synchronize packets
//if(last_rx_time>=BUS_IDLE_TIME)
//{
cmd_receiving = RECV_IDLE;
//TXEN_485 = 1;
//delay_us(10);
//TXEN_485 = 0;
}
//}
}
if (cmd_receiving == RECV_IDLE)
{
cmd_receiving = RECV_READ_HEADER;
UART_Receive_IT(recv_buffer, MODBUS_HEADER_SIZE, 5000);
if(HAL_UARTEx_ReceiveToIdle_DMA(&huart1, recv_buffer, BUFFERS_SIZE)==HAL_OK)
{
cmd_receiving = RECV_READ_HEADER;
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
}
else if (cmd_receiving == RECV_READ_COMPLETE)
{
@@ -98,7 +104,8 @@ void modbus_loop_iterate()
}
else if (cmd_sending == SEND_BUSY && bytes_to_send != 0)
{
UART_Transmit_IT(send_buffer, bytes_to_send, 1000);
TXEN_ON;
HAL_UART_Transmit_DMA(&huart1, send_buffer, bytes_to_send);
bytes_to_send = 0;
}
}