Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoarProto v1.3.3 - UART Patch #10

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions ProtocolTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ constexpr uint8_t PROTOCOL_TASK_PERIOD = 100;
* @brief Constructor, sets all member variables
*/
ProtocolTask::ProtocolTask(Proto::Node node, UART_HandleTypeDef* huart, uint16_t uartTaskCmd) : Task(TASK_PROTOCOL_QUEUE_DEPTH_OBJS),
uartTaskCommand(uartTaskCmd)
uartTaskCommand(uartTaskCmd), numUartErrors_(0)
{
// Setup Buffers
protocolRxBuffer = soar_malloc(PROTOCOL_RX_BUFFER_SZ_BYTES+1);
Expand Down Expand Up @@ -144,6 +144,11 @@ void ProtocolTask::Run(void * pvParams)
UARTTask::Inst().SendCommandReference(protoTx);
break;
}
case EVENT_UART_INTERRUPT_ARM_ERROR: {
// Attempt to receive data again
ReceiveData();
break;
}
default:
break;
}
Expand All @@ -158,8 +163,50 @@ void ProtocolTask::Run(void * pvParams)
*/
bool ProtocolTask::ReceiveData()
{
HAL_UART_Receive_IT((UART_HandleTypeDef*)uartHandle, &protocolRxChar, 1);
return true;
// If HAL_UART_Receive_IT succeeds, return true
if (HAL_OK == HAL_UART_Receive_IT((UART_HandleTypeDef*)uartHandle, &protocolRxChar, 1)) {
numUartErrors_ = 0;
return true;
}

// If we had an error attempt to abort the receive and re-arm the interrupt
HAL_UART_AbortReceive((UART_HandleTypeDef*)uartHandle);

// Attempt to arm the interrupt again, if success return true
if (HAL_OK == HAL_UART_Receive_IT((UART_HandleTypeDef*)uartHandle, &protocolRxChar, 1)) {
numUartErrors_ = 0;
return true;
}

// If we've reached the full number of errors, reset the system
if (++numUartErrors_ >= PROTOCOL_MAX_NUM_ERRORS_UNTIL_RESET) {
SOAR_ASSERT(false, "UART Error Limit Reached -- Board Resetting\n");
}

// Delay then try again next task cycle until the error limit is reached
osDelay(PROTOCOL_UART_RX_ERROR_RETRY_DELAY_MS);
Command cm(PROTOCOL_COMMAND, EVENT_UART_INTERRUPT_ARM_ERROR);
qEvtQueue->Send(cm);

return false;
}

/**
* @brief Receive data from ISR, currently receives by arming interrupt
*/
bool ProtocolTask::ReceiveDataFromISR()
{
// If HAL_UART_Receive_IT succeeds, return true
if (HAL_OK == HAL_UART_Receive_IT((UART_HandleTypeDef*)uartHandle, &protocolRxChar, 1)) {
numUartErrors_ = 0;
return true;
}

// We had an error arming the interrupt, handle this in the next task cycle
Command cm(PROTOCOL_COMMAND, EVENT_UART_INTERRUPT_ARM_ERROR);
qEvtQueue->SendFromISR(cm);

return false;
}

/**
Expand Down Expand Up @@ -254,7 +301,7 @@ void ProtocolTask::InterruptRxData()
}

//Re-arm the interrupt
ReceiveData();
ReceiveDataFromISR();
}

/**
Expand Down
11 changes: 10 additions & 1 deletion ProtocolTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ enum PROTOCOL_TASK_COMMANDS {
PROTOCOL_TASK_COMMAND_NONE = 0,
EVENT_PROTOCOL_RX_COMPLETE,
PROTOCOL_RX_DECODED_DATA,
PROTOCOL_TX_REQUEST_DATA
PROTOCOL_TX_REQUEST_DATA,

EVENT_UART_INTERRUPT_ARM_ERROR
};

/* Macros ------------------------------------------------------------------*/
Expand All @@ -43,6 +45,10 @@ constexpr uint8_t PROTOCOL_CHECKSUM_BYTES = 2;
constexpr uint8_t PROTOCOL_OVERHEAD_BYTES = 1 + PROTOCOL_CHECKSUM_BYTES; // Size of the protocol overhead *PRE-COBS* (message ID + 2 byte checksum)
constexpr uint16_t PROTOCOL_MINIMUM_MESSAGE_LENGTH = PROTOCOL_OVERHEAD_BYTES + 1;

// Error Handling
constexpr uint8_t PROTOCOL_MAX_NUM_ERRORS_UNTIL_RESET = 200; // Number of consecutive UART errors before a system reset is triggered
constexpr uint16_t PROTOCOL_UART_RX_ERROR_RETRY_DELAY_MS = 1; // Delay between UART error retries

/* Class ------------------------------------------------------------------*/
class ProtocolTask : public Task
{
Expand Down Expand Up @@ -72,6 +78,7 @@ class ProtocolTask : public Task
virtual void HandleProtobufTelemetryMessage(EmbeddedProto::ReadBufferFixedSize<PROTOCOL_RX_BUFFER_SZ_BYTES>& readBuffer) = 0;

bool ReceiveData();
bool ReceiveDataFromISR();

// Helper functions

Expand All @@ -89,6 +96,8 @@ class ProtocolTask : public Task

const UART_HandleTypeDef* uartHandle;
const uint16_t uartTaskCommand;

uint8_t numUartErrors_;
};

#endif // SOAR_SYSTEM_PROTOCOL_TASK_HPP_