PingPong/Core/Src/UART3_Handler.c
2024-09-22 00:19:50 +03:00

339 lines
9.5 KiB
C
Raw 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.

/*
* UART3_Handler.c
*
* Created on: Sep 12, 2024
* Author: DashyFox
*/
#include "UART3_Handler.h"
#include "UART3_CMD_Handler.h"
#include "Print.h"
#include "SimpleTimer.h"
uint8_t uart_rx_buffer[UART_BUFFER_SIZE];
uint8_t uart_rx_buffer_out[UART_BUFFER_SIZE];
volatile uint8_t uart_rx_comlite = 0;
extern UART_HandleTypeDef huart3;
void UART3_CMD_Handler(uint8_t *dataPtr, uint8_t len);
void UART3_START() {
HAL_UART_Receive_DMA(&huart3, uart_rx_buffer, UART_BUFFER_SIZE);
}
volatile uint32_t last_rx_time = 0;
volatile uint32_t rx_complete_timeout = 15;
volatile uint32_t old_pos = 0;
volatile uint16_t rx_index = 0;
extern DMA_HandleTypeDef hdma_usart3_rx;
void handle_rx_complete(uint8_t *data, uint16_t len)
{
// Проверка, если данных пришло меньше двух байт
if (len < 2) {
char error_msg[64];
snprintf(error_msg, sizeof(error_msg),
"Received less than 2 bytes: len = %d\n", len);
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
return;
}
// // Распечатать пришедший буфер с указанием номеров байт
// char byte_msg[128];
// snprintf(byte_msg, sizeof(byte_msg), "Received buffer (%d bytes):\n", len);
// CDC_Transmit_FS((uint8_t*) byte_msg, strlen(byte_msg));
//
// for (uint16_t i = 0; i < len; i++) {
// char byte_info[32];
// snprintf(byte_info, sizeof(byte_info), "Byte %d: 0x%02X\n", i, data[i]);
// CDC_Transmit_FS((uint8_t*) byte_info, strlen(byte_info));
// }
// Проверка 0xF0
if (data[0] != 0xF0) {
char error_msg[64];
snprintf(error_msg, sizeof(error_msg),
"Wrong fix 0xF0: received 0x%02X\n", data[0]);
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
return;
}
// Проверка длины пакета
uint8_t length = data[1];
if (length + 3 > UART_BUFFER_SIZE) {
char error_msg[128];
snprintf(error_msg, sizeof(error_msg),
"Packet length exceeds buffer size: received length = %d, max size = %d\n",
length + 3, UART_BUFFER_SIZE);
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
return;
}
// Проверка контрольной суммы
uint16_t checksum = 0;
for (uint8_t i = 0; i < length + 2; i++) {
checksum += data[i];
}
checksum %= 0xFF;
if (checksum != data[length + 2]) {
char error_msg[64];
snprintf(error_msg, sizeof(error_msg),
"Wrong checksum: calculated 0x%02X, received 0x%02X\n",
checksum, data[length + 2]);
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
return;
}
// CDC_Transmit_FS((uint8_t*)"\n\n", 2);
uint8_t *data_ptr = &data[2];
UART3_CMD_Handler(data_ptr, length);
}
void handle_rx_data(uint8_t* data, uint16_t len)
{
if (len > 0)
{
if(!rx_index){
memset(uart_rx_buffer_out, 0x00, UART_BUFFER_SIZE);
}
memcpy(uart_rx_buffer_out+rx_index, data, len);
rx_index += len;
// uint8_t ff = 0xFF;
// CDC_Transmit_FS(&ff, 1);
}
}
void process_uart_data(uint32_t old_pos, uint32_t new_pos)
{
if (new_pos > old_pos)
{
// Обрабатываем данные между old_pos и new_pos
handle_rx_data(&uart_rx_buffer[old_pos], new_pos - old_pos);
}
else
{
// Обрабатываем данные от old_pos до конца буфера и от начала до new_pos
handle_rx_data(&uart_rx_buffer[old_pos], UART_BUFFER_SIZE - old_pos);
handle_rx_data(&uart_rx_buffer[0], new_pos);
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
{
char error_msg[128];
// Логгирование состояния до перезапуска
snprintf(error_msg, sizeof(error_msg),
"UART3 Error Detected: Code = 0x%02X, DMA Counter = %lu\n",
huart->ErrorCode, __HAL_DMA_GET_COUNTER(&hdma_usart3_rx));
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
// Останавливаем UART и DMA
HAL_UART_DMAStop(huart);
// Очищаем флаги всех возможных ошибок
__HAL_UART_CLEAR_FEFLAG(huart); // Сброс ошибки кадра
__HAL_UART_CLEAR_PEFLAG(huart); // Сброс ошибки четности
__HAL_UART_CLEAR_NEFLAG(huart); // Сброс ошибки шума
__HAL_UART_CLEAR_OREFLAG(huart); // Сброс ошибки переполнения
// Проверка, не повторяется ли ошибка через несколько циклов
static int error_count = 0;
error_count++;
if (error_count > 1)
{
NVIC_SystemReset(); // Полный перезапуск системы после n ошибок
}
// Деинициализация и повторная инициализация UART
HAL_UART_DeInit(huart);
HAL_UART_Init(huart);
// Перезапуск DMA
HAL_UART_Receive_DMA(huart, uart_rx_buffer, UART_BUFFER_SIZE);
// Логгирование состояния после перезапуска
snprintf(error_msg, sizeof(error_msg),
"UART3 DMA reception restarted: DMA Counter = %lu\n",
__HAL_DMA_GET_COUNTER(&hdma_usart3_rx));
CDC_Transmit_FS((uint8_t*) error_msg, strlen(error_msg));
}
}
uint8_t rx_in_progress = 0;
void UART3_Handler() {
uint32_t pos = UART_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
if (pos != old_pos)
{
last_rx_time = millis();
rx_in_progress = 1;
process_uart_data(old_pos, pos);
old_pos = pos;
}
else if (rx_in_progress && (millis() - last_rx_time) > rx_complete_timeout)
{
handle_rx_complete(uart_rx_buffer_out, rx_index);
rx_index = 0;
last_rx_time = millis();
rx_in_progress = 0;
}
}
void SendResponse(uint8_t command, uint8_t result, uint8_t *data, uint8_t data_length) {
uint8_t response_buffer[64];
uint8_t index = 0;
response_buffer[index++] = 0xF0; // Начальный байт
response_buffer[index++] = data_length + 2; // Длина данных + 2 байта (команда, результат)
response_buffer[index++] = command; // Команда
response_buffer[index++] = result; // Результат
if (data != NULL && data_length > 0) {
for (uint8_t i = 0; i < data_length; i++) {
response_buffer[index++] = data[i];
}
}
uint16_t checksum = 0;
for (uint8_t i = 0; i < index; i++) {
checksum += response_buffer[i];
}
checksum %= 0xFF;
response_buffer[index++] = checksum;
// // Печать пакета в CDC с нумерацией байт
// char byte_msg[128];
// snprintf(byte_msg, sizeof(byte_msg), "Sending response buffer (%d bytes):\n", index);
// CDC_Transmit_FS((uint8_t*) byte_msg, strlen(byte_msg));
//
// for (uint8_t i = 0; i < index; i++) {
// char byte_info[32];
// snprintf(byte_info, sizeof(byte_info), "Byte %d: 0x%02X\n", i, response_buffer[i]);
// CDC_Transmit_FS((uint8_t*) byte_info, strlen(byte_info));
// }CDC_Transmit_FS((uint8_t*) "\n\n", 2);
HAL_UART_Transmit(&huart3, response_buffer, index, HAL_MAX_DELAY);
}
void UART3_CMD_Handler(uint8_t *dataPtr, uint8_t len) {
uint8_t command = dataPtr[0];
if(command != 0xb5){
print("Received command: ");
printNumber(command);
print("\nParameters: [");
for (uint8_t i = 1; i < len; i++) {
printNumber(dataPtr[i]);
if (i < len - 1) {
print(", ");
}
}
print("]\n");
}
switch (command) {
case 10:
UART3_SaveShot(dataPtr, len);
break;
case 11:
UART3_SaveProgram(dataPtr, len);
break;
case 12:
UART3_SaveMacro(dataPtr, len);
break;
case 100:
UART3_StartMacro(dataPtr, len);
break;
case 101:
UART3_StartProgram(dataPtr, len);
break;
case 102:
UART3_StartShot(dataPtr, len);
break;
case 110:
UART3_Stop(dataPtr, len);
break;
case 13:
UART3_DeleteShot(dataPtr, len);
break;
case 14:
UART3_DeleteProgram(dataPtr, len);
break;
case 15:
UART3_DeleteMacro(dataPtr, len);
break;
case 120:
UART3_DeleteAllData(dataPtr, len);
break;
case 180:
UART3_GetDeviceStatus(dataPtr, len);
break;
case 200:
UART3_SetServoOffset(dataPtr, len);
break;
case 201:
UART3_SetServoMaxAngle(dataPtr, len);
break;
case 202:
UART3_SetServoMinAngle(dataPtr, len);
break;
case 203:
UART3_MoveServoToInitialPosition(dataPtr, len);
break;
// case 204:
// UART3_GetServoOffset(dataPtr, len);
// break;
case 205:
UART3_GetServoOffset(dataPtr, len);
break;
case 206:
UART3_SetStartupDelay(dataPtr, len);
break;
case 207:
UART3_GetStartupDelay(dataPtr, len);
break;
case 210:
UART3_SetMinRollerSpeed(dataPtr, len);
break;
case 211:
UART3_GetMinRollerSpeed(dataPtr, len);
break;
case 212:
UART3_SetMinScrewSpeed(dataPtr, len);
break;
case 213:
UART3_GetMinScrewSpeed(dataPtr, len);
break;
case 214:
UART3_SetServoInvertFlag(dataPtr, len);
break;
case 215:
UART3_GetServoInvertFlag(dataPtr, len);
break;
case 181:
UART3_ReadStatistics(dataPtr, len);
break;
case 121:
UART3_ResetStatistics(dataPtr, len);
break;
default:
print("Unknown command");
break;
}
}