Reorganizing project
This commit is contained in:
parent
2d6567b1b2
commit
76ba80db36
51 changed files with 139 additions and 266 deletions
237
components/f4ll/src/ll_hsusart.cpp
Normal file
237
components/f4ll/src/ll_hsusart.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* ll_hsusart_impl.h
|
||||
*
|
||||
* Created on: Oct 29, 2019
|
||||
* Author: abody
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "f4ll/ll_hsusart.h"
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
template<typename T> static inline T RoundUpTo4(T input)
|
||||
{
|
||||
return (input + 3) & (((T)-1) - 3);
|
||||
}
|
||||
|
||||
|
||||
LL_HsUsart::LL_HsUsart(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t streamRx, uint32_t streamTx)
|
||||
: LL_UsartCore(usart, dma, streamRx, streamTx)
|
||||
{
|
||||
LL_CrcHandler::Instance().AttachSlot(m_crcSlot);
|
||||
}
|
||||
|
||||
|
||||
uint8_t *LL_HsUsart::GetTxPacketBuffer(void)
|
||||
{
|
||||
return m_txBuffer.packet.payload;
|
||||
}
|
||||
|
||||
|
||||
USART_TypeDef* LL_HsUsart::GetUsart(void)
|
||||
{
|
||||
return m_usart;
|
||||
}
|
||||
|
||||
|
||||
LL_HsUsart::Stats const & LL_HsUsart::GetStats(void)
|
||||
{
|
||||
return m_stats;
|
||||
}
|
||||
|
||||
|
||||
bool LL_HsUsart::IsTxBusy()
|
||||
{
|
||||
return m_txBuffer.busy;
|
||||
}
|
||||
|
||||
|
||||
bool LL_HsUsart::IsTxFailed()
|
||||
{
|
||||
return m_txBuffer.error;
|
||||
}
|
||||
|
||||
|
||||
bool LL_HsUsart::IsRxBusy(bool second)
|
||||
{
|
||||
return m_rxBuffers[second].busy;
|
||||
}
|
||||
|
||||
|
||||
bool LL_HsUsart::IsRxFailed(bool second)
|
||||
{
|
||||
return m_rxBuffers[second].error;
|
||||
|
||||
}
|
||||
|
||||
void LL_HsUsart::RxProcessed(bool second)
|
||||
{
|
||||
m_rxBuffers[second].busy = false;
|
||||
m_rxBuffers[second].error = false;
|
||||
}
|
||||
|
||||
void LL_HsUsart::SetCallback(IHsUsartCallback *callback, uintptr_t callbackParam)
|
||||
{
|
||||
m_userCallback = callback;
|
||||
m_userCallbackParam = callbackParam;
|
||||
}
|
||||
|
||||
void LL_HsUsart::BuildHeader(Packet &packet, uint8_t serialNo, uint8_t length)
|
||||
{
|
||||
uint8_t hash = STARTMARKER;
|
||||
|
||||
packet.header.startByte = STARTMARKER;
|
||||
packet.header.serial = serialNo;
|
||||
hash ^= serialNo;
|
||||
packet.header.payloadLength = length;
|
||||
hash ^= length;
|
||||
packet.header.hash = hash;
|
||||
}
|
||||
|
||||
|
||||
bool LL_HsUsart::CheckHeader(PacketHeader &header)
|
||||
{
|
||||
return header.startByte == STARTMARKER && (header.startByte ^ header.serial ^ header.payloadLength) == header.hash;
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::PostPacket(uint8_t const *payload, uint8_t length, bool waitForCrcQueue)
|
||||
{
|
||||
uint16_t payloadLength = RoundUpTo4((uint16_t)length);
|
||||
|
||||
BuildHeader(m_txBuffer.packet, m_txSerialNo++, length);
|
||||
if(payload)
|
||||
memcpy(m_txBuffer.packet.payload, payload, length);
|
||||
m_txBuffer.requestedLength = sizeof(m_txBuffer.packet.header) + payloadLength + sizeof(uint32_t);
|
||||
m_txBuffer.busy = true;
|
||||
m_txBuffer.error = false;
|
||||
|
||||
LL_CrcHandler::Instance().Enqueue(m_crcSlot, 0, &m_txBuffer.packet, sizeof(PacketHeader) + payloadLength,
|
||||
nullptr, reinterpret_cast<uintptr_t>(m_txBuffer.packet.payload + payloadLength));
|
||||
|
||||
while(waitForCrcQueue && LL_CrcHandler::Instance().IsQueued(m_crcSlot, 0));
|
||||
|
||||
SetupTransmit(&m_txBuffer.packet, m_txBuffer.requestedLength);
|
||||
|
||||
++m_stats.sent;
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::SetupReceive()
|
||||
{
|
||||
m_rxBuffers[m_rxBufferSelector].requestedLength = sizeof(m_rxBuffers[m_rxBufferSelector].packet);
|
||||
LL_UsartCore::SetupReceive(&m_rxBuffers[m_rxBufferSelector], sizeof(m_rxBuffers[m_rxBufferSelector].packet));
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::ReceiverIdle(void)
|
||||
{
|
||||
uint16_t rcvdLen = m_rxBuffers[m_rxBufferSelector].requestedLength - LL_DMA_GetDataLength(m_rxDma.GetDma(), m_rxDma.GetStream());
|
||||
if(rcvdLen >= sizeof(PacketHeader)) {
|
||||
if(CheckHeader(m_rxBuffers[m_rxBufferSelector].packet.header)) {
|
||||
if(rcvdLen >= sizeof(PacketHeader) +
|
||||
RoundUpTo4((uint16_t)m_rxBuffers[m_rxBufferSelector].packet.header.payloadLength)
|
||||
+ sizeof(uint32_t))
|
||||
LL_DMA_DisableStream(m_rxDma.GetDma(), m_rxDma.GetStream());
|
||||
else
|
||||
++m_stats.premature_payload;
|
||||
} else {
|
||||
m_rxBuffers[m_rxBufferSelector].error = 1;
|
||||
LL_DMA_DisableStream(m_rxDma.GetDma(), m_rxDma.GetStream());
|
||||
}
|
||||
} else
|
||||
++m_stats.premature_hdr;
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::TransmissionComplete(void)
|
||||
{
|
||||
LL_USART_DisableDirectionTx(m_usart); // enforcing an idle frame
|
||||
LL_USART_EnableDirectionTx(m_usart);
|
||||
m_txBuffer.busy = 0;
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::RxDmaTransferComplete(void)
|
||||
{
|
||||
if(CheckHeader(m_rxBuffers[m_rxBufferSelector].packet.header))
|
||||
LL_CrcHandler::Instance().Enqueue(m_crcSlot, 1,
|
||||
&m_rxBuffers[m_rxBufferSelector].packet,
|
||||
sizeof(PacketHeader) + RoundUpTo4((uint16_t)m_rxBuffers[m_rxBufferSelector].packet.header.payloadLength),
|
||||
this, m_rxBufferSelector);
|
||||
else {
|
||||
++m_stats.hdrError;
|
||||
m_rxBuffers[m_rxBufferSelector].error = true;
|
||||
}
|
||||
SwitchRxBuffers();
|
||||
}
|
||||
|
||||
void LL_HsUsart::RxDmaHalfTransfer(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::RxDmaError(LL_DmaHelper::DmaErrorType reason)
|
||||
{
|
||||
m_rxBuffers[m_rxBufferSelector].error = 1;
|
||||
++m_stats.rxDmaError;
|
||||
SwitchRxBuffers();
|
||||
}
|
||||
|
||||
void LL_HsUsart::TxDmaTransferComplete(void)
|
||||
{
|
||||
LL_USART_EnableIT_TC(m_usart);
|
||||
LL_DMA_DisableStream(m_txDma.GetDma(), m_txDma.GetStream());
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::TxDmaHalfTransfer(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::TxDmaError(LL_DmaHelper::DmaErrorType reason)
|
||||
{
|
||||
m_txBuffer.error = 1;
|
||||
++m_stats.txDmaError;
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::SwitchRxBuffers(void)
|
||||
{
|
||||
++m_stats.rcvd;
|
||||
m_rxBufferSelector = !m_rxBufferSelector;
|
||||
|
||||
if(m_rxBuffers[m_rxBufferSelector].busy)
|
||||
++m_stats.overrun;
|
||||
SetupReceive();
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio)
|
||||
{
|
||||
Buffer &buf(m_rxBuffers[static_cast<int>(callbackParam)]);
|
||||
|
||||
buf.busy = 1;
|
||||
if(*(uint32_t*) (buf.packet.payload + RoundUpTo4((uint16_t)buf.packet.header.payloadLength)) != crc) {
|
||||
buf.error = 1;
|
||||
buf.errorInfo = crc;
|
||||
++m_stats.payloadErrror;
|
||||
}
|
||||
if(m_userCallback)
|
||||
buf.busy = !m_userCallback->PacketReceived(this, m_userCallbackParam, buf.packet);
|
||||
}
|
||||
|
||||
|
||||
void LL_HsUsart::CrcFailed(uintptr_t callbackParam, uint32_t crc, int prio)
|
||||
{
|
||||
Buffer &buf(m_rxBuffers[static_cast<int>(callbackParam)]);
|
||||
buf.busy = buf.error = true;
|
||||
buf.errorInfo = 0;
|
||||
++m_stats.payloadErrror;
|
||||
if(m_userCallback)
|
||||
buf.busy = !m_userCallback->PacketReceived(this, m_userCallbackParam, buf.packet);
|
||||
}
|
||||
|
||||
|
||||
} // namespace f4ll
|
Loading…
Add table
Add a link
Reference in a new issue