UART Module - smartel99/NilaiTFO GitHub Wiki
The UART Module is rather simple in it's usage, yet offers a very complete API for diverse use cases.
To instantiate a UART module in your application, you must first configure it in the CubeMX software.
Don't forget to call the MX_UARTx_Init
function before instantiating the UART module!
To instantiate the module in your application:
void MyApplication::InitializeModules()
{
AddModule(new UartModule(&hurt4, "uart4"));
}
The constructor of UartModule
takes a pointer to a UART_HandleTypeDef
created by the Cube and a string that is used to identify the module.
To simplify access to this new instance, you can create a macro that will get that instance in the application like such:
#define UART4_MODULE() static_cast<UartModule*>(MyApplication::GetModule("uart4")
This allows it to be used like this:
UART4_MODULE()->Transmit("A message to be sent\n\r");
The UART Module API offers a few configuration option, mainly concerning packet reception.
This option configures the module to call a reception completed once a certain number of bytes is received, including the start and end of frame, if present.
To set this option, use the SetExpectedRxLen
method of UartModule
, which takes the desired length as parameter.
myUart.SetExpectedRxLen(10); // We expect 10 bytes.
You can clear this option if desired using the ClearExpectedRxLen
method.
If you want to set a start of frame for your UART module, simply use the SetStartOfFrameSequence
method, which takes a std::string
, a std::vector<uint8_t>
or a pair of uint8_t*
and size_t
.
The module will only start saving the data being received once the start of frame sequence has been received.
myUart.SetStartOfFrameSequence("sof");
To clear it, use the ClearStartOfFrameSequence
method.
Similarly to the Start of Frame, you can set an End of Frame sequence for your UART module using the SetEndOfFrameSequence
method.
The module will consider the packet as complete as soon as the end of frame sequence is received, independent of the expected size (More or less data may be received).
myUart.SetEndOfFrameSequence("eof");
To clear it, use the ClearEndOfFrameSequence
method.
You can set a function to be called once a frame has been received by the module using the SetFrameReceiveCpltCallback
method, which takes a std::function<void()>
as parameter.
This function, which can be a lambda, is called as soon as m_expectedLen
bytes of data is received, or if it is set, as soon as the end of frame sequence is called.
Using a function pointer:
void MyCallback()
{
UART::Frame frame = UART4_MODULE->Receive();
// Do stuff with the frame.
}
void MyApplication::InitializeModules()
{
AddModule(new UartModule(&hurt4, "uart4"));
UART4_MODULE->SetFrameReceiveCpltCallback(&MyCallback);
}
Using a lambda:
void MyApplication::InitializeModules()
{
AddModule(new UartModule(&hurt4, "uart4"));
UART4_MODULE->SetFrameReceiveCpltCallback([]()
{
UART::Frame frame = UART4_MODULE->Receive();
// Do stuff with the frame.
});
}
To clear the callback, use the ClearFrameReceiveCpltCallback
method.
To transmit something with the UartModule, simply use the Transmit
method.
UART4_MODULE->Transmit("My message");
To receive a frame from the UartModule, you can use the GetNumberOfWaitingFrames
method to get how many frames are ready to be read, then use the Receive
method to receive a UART::Frame
.
The UART::Frame
type is a structure containing a std::string
called data
, and a uint32_t
called timestamp
.
if(UART4_MODULE->GetNumberOfWaitingFrames() > 0)
{
UART::Frame frame = UART4_MODULE->Receive();
// Do stuff with it.
}
Of course, if we want to receive a frame in the callback function called by the module, we don't have to check the number of frames waiting, since we know for sure that there is at least one.