mirror of
https://github.com/DashyFox/StackSport.git
synced 2025-05-04 07:10:17 +00:00
294 lines
7.6 KiB
C
294 lines
7.6 KiB
C
/*
|
||
* 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 = 10;
|
||
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);
|
||
}
|
||
}
|
||
volatile uint8_t rx_in_progress = 0;
|
||
void check_uart3_timeout(void)
|
||
{
|
||
|
||
}
|
||
|
||
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 204:
|
||
UART3_GetServoOffset(dataPtr, len);
|
||
break;
|
||
case 201:
|
||
UART3_SetServoMaxAngle(dataPtr, len);
|
||
break;
|
||
case 202:
|
||
UART3_GetServoMaxAngle(dataPtr, len);
|
||
break;
|
||
case 203:
|
||
UART3_MoveServoToInitialPosition(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;
|
||
}
|
||
}
|
||
|