/* * 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; } }