/*
 * packetusart_unittest.cpp
 *
 *  Created on: Dec 2, 2019
 *      Author: abody
 */
#include <stdlib.h>
#include <inttypes.h>
#include <thread>
#include <future>

#include <platform/usart_ll.h>
#include <f4ll_c/packetusart.h>

#include <CppUTest/TestHarness.h>
#include <CppUTestExt/MockSupport.h>
#include <subhook.h>


//static inline uint32_t RoundUpTo4(uint32_t inp)
//{
//	return (inp + 3) & 0xfffc;
//}
//
//DMA_TypeDef* DMA1  __attribute__((weak));
//DMA_TypeDef* DMA2  __attribute__((weak));
//
//static DMA_TypeDef fakeDma1, fakeDma2;
//static CRC_TypeDef fakeCrc;
//static USART_TypeDef fakeUsart;
//
//static struct usartstatus_t usartStatus;
//static struct crcstatus_t crcStatus;
//
//uint8_t testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//
////static uint32_t expected_stream;
////static uint32_t expected_srcaddress;
////static uint32_t expected_dstaddress;
////static uint32_t expected_length;
////static void *expected_customptr;
////static uint8_t expected_success;
////static struct usartstatus_t * expectedUsartStatus;
//static uint32_t expectedStreams[2] = { 0,7 };
//struct crcstatus_t *expectedCrcStatus;
//struct crcslot_t *expectedCrcSlotListItem;
//struct crctask_t *expectedTasks;
//uint8_t expectedTaskCount;
//uint32_t expectedCrcLength;
//uint32_t expectedLength;
//void* expectedCrcEnqueueAddress;
//void *expectedTransmitBuffer;
//
//static uint32_t expectedStream;
//uint32_t expectedSrcAddress;
//uint32_t expectedDstAddress;
//uint32_t expectedDirection;
//
//uint32_t fakePacketReceivedCallbackParam;
//
//
//// this isn't a real mov but we use the mockinginfrastructure
//// to automate administration (call count, etc)
//DEFINE_MOCK(FakePacketReceivedCallback, mock, void* userParam, struct usart_buffer_t *buffer)
//{
//	EXPECT_EQ((void*)&fakePacketReceivedCallbackParam, userParam);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(Dma_Init, mock, struct dmainfo_t* dmaInfo, DMA_TypeDef *dma, uint32_t stream)
//{
//	Dma_Init__(dmaInfo, dma, stream);
// 	LEAVE_MOCK
//}
//
//DEFINE_MOCK(Crc_AttachTasks, mock, struct crcstatus_t *status, struct crcslot_t *slot, struct crctask_t *tasks, uint8_t taskCount)
//{
//	EXPECT_EQ(status, expectedCrcStatus);
//	EXPECT_EQ(slot, expectedCrcSlotListItem);
//	EXPECT_EQ(tasks, expectedTasks);
//	EXPECT_EQ(taskCount, expectedTaskCount);
//	Crc_AttachTasks__(status, slot, tasks, taskCount);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_DMA_EnableIT_TC, init, DMA_TypeDef *dma, uint32_t stream)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStreams[MOCK_VAR(LL_DMA_EnableIT_TC, init, callcount)-1]);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_DMA_EnableIT_TE, init, DMA_TypeDef *dma, uint32_t stream)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStreams[MOCK_VAR(LL_DMA_EnableIT_TE, init, callcount)-1]);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_USART_DMA_GetRegAddr, mock, USART_TypeDef *usart)
//{
//	RETURN_MOCK_PREDEF(LL_USART_DMA_GetRegAddr, mock)
//}
//
//DEFINE_MOCK(LL_DMA_ConfigAddresses, mock, DMA_TypeDef* dma, uint32_t stream, uint32_t srcAddress, uint32_t dstAddress, uint32_t direction)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStream);
//	EXPECT_EQ(srcAddress, expectedSrcAddress);
//	EXPECT_EQ(dstAddress, expectedDstAddress);
//	EXPECT_EQ(direction, expectedDirection);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_DMA_SetDataLength, mock, DMA_TypeDef* dma, uint32_t stream, uint32_t length)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStream);
//	EXPECT_EQ(length, expectedLength);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_DMA_GetDataLength, mock, DMA_TypeDef* dma, uint32_t stream)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStream);
//	RETURN_MOCK_PREDEF(LL_DMA_GetDataLength, mock)
//}
//
//DEFINE_MOCK(LL_DMA_EnableStream, mock, DMA_TypeDef* dma, uint32_t stream)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStream);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_DMA_DisableStream, mock, DMA_TypeDef* dma, uint32_t stream)
//{
//	EXPECT_EQ(dma, &fakeDma1);
//	EXPECT_EQ(stream, expectedStream);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_EnableDMAReq_TX, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_EnableDMAReq_RX, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_EnableIT_IDLE, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_EnableIT_TC, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_DisableIT_TC, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_USART_IsActiveFlag_IDLE, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	RETURN_MOCK_PREDEF(LL_USART_IsActiveFlag_IDLE, mock)
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_USART_IsActiveFlag_TC, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	RETURN_MOCK_PREDEF(LL_USART_IsActiveFlag_TC, mock)
//}
//
//DEFINE_MOCK(LL_USART_ClearFlag_IDLE, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK;
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_USART_IsEnabledIT_IDLE, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	RETURN_MOCK_PREDEF(LL_USART_IsEnabledIT_IDLE, mock)
//}
//
//DEFINE_MOCK_RET(uint32_t, LL_USART_IsEnabledIT_TC, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	RETURN_MOCK_PREDEF(LL_USART_IsEnabledIT_TC, mock)
//}
//
//DEFINE_MOCK(LL_USART_EnableDirectionTx, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_DisableDirectionTx, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK(LL_USART_ClearFlag_ORE, mock, USART_TypeDef *usart)
//{
//	EXPECT_EQ(usart, &fakeUsart);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK_RET(uint8_t, Crc_Enqueue, mock, struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task,
//		void *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam)
//{
//	EXPECT_EQ(expectedCrcLength, len);
//	EXPECT_EQ(expectedCrcEnqueueAddress, address);
//	RETURN_MOCK_PREDEF(Crc_Enqueue, mock);
//}
//
//DEFINE_MOCK_RET(uint8_t, Crc_IsTaskQueued, mock, struct crcslot_t *slot, uint8_t task)
//{
//	RETURN_MOCK_PREDEF(Crc_IsTaskQueued, mock);
//}
//
//DEFINE_MOCK(Pu_SetupTransmit, mock, USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length)
//{
//	EXPECT_EQ(buffer, expectedTransmitBuffer);
//	EXPECT_EQ(length, expectedLength);
//	LEAVE_MOCK
//}
//
//DEFINE_MOCK_RET(uint8_t, Pu_CheckHeader, proxy, struct usartpacket_t *packet)
//{
//	RETURN_MOCK(Pu_CheckHeader, proxy, Pu_CheckHeader__(packet));
//}
//
//DEFINE_MOCK(Pu_SetupReceive, mock, struct usartstatus_t *status)
//{
//	LEAVE_MOCK
//}
//
//struct PacketUsart : public ::testing::Test {
//	void SetUp()
//	{
//		DMA1 = &fakeDma1;
//		DMA2 = &fakeDma2;
//
//		memset(&usartStatus, 0x5a, sizeof(usartStatus));
//		Crc_InitStatus(&crcStatus, &fakeCrc, &fakeDma2, 4);
//
//		expectedCrcStatus = &crcStatus;
//		expectedCrcSlotListItem = &usartStatus.crcSlot;
//		expectedTasks = usartStatus.crcTasks;
//		expectedTaskCount = 2;
//	}
//};
//
////////////////////////////////////////////////////////////////////////////////
//TEST_F(PacketUsart, Init)
//{
//	ACTIVATE_MOCK(Dma_Init, mock);
//	ACTIVATE_MOCK(Crc_AttachTasks, mock);
//	ACTIVATE_MOCK(LL_DMA_EnableIT_TC, init);
//	ACTIVATE_MOCK(LL_DMA_EnableIT_TE, init);
//	ACTIVATE_MOCK(LL_USART_EnableIT_IDLE, mock);
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//
//	EXPECT_EQ(fakeDma1.LIFCR, DMA_LISR_TCIF0 | DMA_LISR_HTIF0 | DMA_LISR_TEIF0 | DMA_LISR_FEIF0 | DMA_LISR_DMEIF0);
//	EXPECT_EQ(fakeDma1.HIFCR, DMA_HISR_TCIF7 | DMA_HISR_HTIF7 | DMA_HISR_TEIF7 | DMA_HISR_FEIF7 | DMA_HISR_DMEIF7);
//	EXPECT_EQ(MOCK_CALLCOUNT(Dma_Init, mock), 2);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_EnableIT_TC, init), 2);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_EnableIT_TE, init), 2);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableIT_IDLE, mock), 1);
//	EXPECT_EQ(usartStatus.usart, &fakeUsart);
//	EXPECT_EQ(usartStatus.txBuffer.usartStatus, &usartStatus);
//	EXPECT_EQ(usartStatus.txBuffer.busy, 0);
//	EXPECT_EQ(usartStatus.txBuffer.error, 0);
//	EXPECT_EQ(usartStatus.txBuffer.requestedLength, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].requestedLength, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].usartStatus, &usartStatus );
//	EXPECT_EQ(usartStatus.rxBuffers[1].busy, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[1].error, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[1].requestedLength, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[1].usartStatus, &usartStatus );
//	EXPECT_TRUE(usartStatus.packetReceivedCallback == FakePacketReceivedCallback_mock);
//	EXPECT_EQ(usartStatus.packetReceivedCallbackParam, &fakePacketReceivedCallbackParam);
//	EXPECT_EQ(usartStatus.rxSerial, (uint8_t)-1);
//	EXPECT_EQ(usartStatus.txSerial, 0);
//	EXPECT_EQ(usartStatus.activeRxBuf, 0);
//	EXPECT_EQ(usartStatus.crcStatus, &crcStatus);
//}
//
//TEST_F(PacketUsart, GetTxBuffer)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	EXPECT_EQ(Pu_GetTxBuffer(&usartStatus), (unsigned char*)&usartStatus.txBuffer.packet.payload);
//}
//
//// SetupTransmit should set all engines (DMA, USART) up properly for starting the transmission
//TEST_F(PacketUsart, SetupTransmit)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	expectedStream = 7;
//	expectedSrcAddress = (uint32_t)testData;
//	expectedDstAddress = (uint32_t)&fakeUsart.DR;
//	expectedDirection = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
//	expectedLength = sizeof(testData);
//
//	ACTIVATE_MOCK(LL_DMA_ConfigAddresses, mock);
//	ACTIVATE_MOCK(LL_DMA_SetDataLength , mock);
//	ACTIVATE_MOCK(LL_DMA_EnableStream , mock);
//	ACTIVATE_MOCK(LL_USART_EnableDMAReq_TX, mock);
//	ACTIVATE_MOCK_RV(LL_USART_DMA_GetRegAddr, mock, expectedDstAddress);
//
//	Pu_SetupTransmit(&fakeUsart, &fakeDma1, 7, testData, sizeof(testData));
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_ConfigAddresses, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_SetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_EnableStream, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableDMAReq_TX, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DMA_GetRegAddr, mock), 1);
//}
//
//// Testing Pu_Post, not waiting for the crc scheduler to start processing our block
//TEST_F(PacketUsart, Post_copy_nowait)
//{
//	struct usartpacketheader_t expectedHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
//	expectedCrcLength = sizeof(usartStatus.txBuffer.packet.header) + 12;
//	expectedCrcEnqueueAddress = &usartStatus.txBuffer.packet;
//	expectedLength = sizeof(usartStatus.txBuffer.packet.header) + 12 + sizeof(uint32_t);
//	expectedTransmitBuffer = &usartStatus.txBuffer.packet;
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//
//	ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
//	ACTIVATE_MOCK(Pu_SetupTransmit, mock);
//	ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 1);
//
//	Pu_Post(&usartStatus, testData, sizeof(testData), false);
//
//	EXPECT_EQ(usartStatus.txBuffer.busy, 1);
//	EXPECT_EQ(usartStatus.txBuffer.requestedLength, expectedLength);
//	EXPECT_EQ(memcmp(&usartStatus.txBuffer.packet.header, &expectedHeader, sizeof(expectedHeader)), 0);
//	EXPECT_EQ(MOCK_CALLCOUNT(Crc_Enqueue, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_SetupTransmit, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsTaskQueued, mock), 0);
//}
//
//// Posting with free CRC engine (will execute our block immediately)
//TEST_F(PacketUsart, Post_copy_wait_nodelay)
//{
//	expectedCrcLength = sizeof(usartStatus.txBuffer.packet.header) + 12;
//	expectedCrcEnqueueAddress = &usartStatus.txBuffer.packet;
//	expectedLength = sizeof(usartStatus.txBuffer.packet.header) + 12 + sizeof(uint32_t);
//	expectedTransmitBuffer = &usartStatus.txBuffer.packet;
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//
//	ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
//	ACTIVATE_MOCK(Pu_SetupTransmit, mock);
//	ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 0);
//
//	Pu_Post(&usartStatus, testData, sizeof(testData), true);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsTaskQueued, mock), 1);
//}
//
//// Posting with with busy CRC engine should block our call
//TEST_F(PacketUsart, Post_copy_wait_delay)
//{
//	expectedCrcLength = sizeof(usartStatus.txBuffer.packet.header) + 12;
//	expectedCrcEnqueueAddress = &usartStatus.txBuffer.packet;
//	expectedLength = sizeof(usartStatus.txBuffer.packet.header) + 12 + sizeof(uint32_t);
//	expectedTransmitBuffer = &usartStatus.txBuffer.packet;
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//
//	ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
//	ACTIVATE_MOCK(Pu_SetupTransmit, mock);
//	ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 1);
//
//	// black magic to test if the function blocks (at least for 100ms)
//	std::promise<bool> promiseFinished;
//	auto futureResult = promiseFinished.get_future();
//	pthread_t th;
//	std::thread t([](std::promise<bool>& finished) {
//		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
//		Pu_Post(&usartStatus, testData, sizeof(testData), true);;
//		finished.set_value(true);
//	}, std::ref(promiseFinished));
//	th = t.native_handle();
//	t.detach();
//	EXPECT_EQ(futureResult.wait_for(std::chrono::milliseconds(100)), std::future_status::timeout);
//	Crc_IsTaskQueued_mock_retval = 0;
//	auto waitResult(futureResult.wait_for(std::chrono::milliseconds(100)));
//	EXPECT_NE(waitResult, std::future_status::timeout);
//	if(waitResult == std::future_status::timeout)
//		pthread_cancel(th);
//}
//
//// HandleTxDmaIrq_tc should enable USART TC interrupt and disable DMA stream
//TEST_F(PacketUsart, HandleTxDmaIrq_tc)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_Post(&usartStatus, testData, sizeof(testData), true);
//
//	memset(&fakeDma1, 0, sizeof(fakeDma1));
//	fakeDma1.HISR = DMA_HISR_TCIF7;
//	expectedStream = 7;
//
//	ACTIVATE_MOCK(LL_USART_EnableIT_TC, mock);
//	ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
//
//	Pu_HandleTxDmaIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableIT_TC, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 1);
//	EXPECT_EQ(fakeDma1.HIFCR, DMA_HIFCR_CTCIF7);
//}
//
//// HandleTxDmaIrq_te should enable USART TC interrupt disable DMA stream and set the error flag
//TEST_F(PacketUsart, HandleTxDmaIrq_te)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_Post(&usartStatus, testData, sizeof(testData), true);
//
//	memset(&fakeDma1, 0, sizeof(fakeDma1));
//	fakeDma1.HISR = DMA_HISR_TEIF7;
//	expectedStream = 7;
//
//	Pu_HandleTxDmaIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableIT_TC, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 1);
//	EXPECT_EQ(fakeDma1.HIFCR, DMA_HIFCR_CTEIF7);
//	EXPECT_EQ(usartStatus.txBuffer.error, 1);
//}
//
//// HandleUsartIrq_tc should disable USART TC interrupt, pulse TX direction enabled to enforce an idle frame
//// and mark the tx buffer as free
//TEST_F(PacketUsart, HandleUsartIrq_tc)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_Post(&usartStatus, testData, sizeof(testData), true);
//
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_IDLE, mock, 0);
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_TC, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_TC, mock, 1);
//	ACTIVATE_MOCK(LL_USART_DisableIT_TC, mock);
//	ACTIVATE_MOCK(LL_USART_EnableDirectionTx, mock);
//	ACTIVATE_MOCK(LL_USART_DisableDirectionTx, mock);
//
//	Pu_HandleUsartIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DisableIT_TC, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DisableDirectionTx, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableDirectionTx, mock), 1);
//	EXPECT_EQ(usartStatus.txBuffer.busy, 0);
//}
//
//// SetupReceive must set USART and DMA engine up for reception
//TEST_F(PacketUsart, SetupReceive)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	expectedStream = 0;
//	expectedDstAddress = (uint32_t)&usartStatus.rxBuffers[usartStatus.activeRxBuf].packet;
//	expectedSrcAddress = (uint32_t)&fakeUsart.DR;
//	expectedDirection = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
//	expectedLength = sizeof(struct usartpacket_t);
//
//	ACTIVATE_MOCK(LL_DMA_ConfigAddresses, mock);
//	ACTIVATE_MOCK(LL_DMA_SetDataLength , mock);
//	ACTIVATE_MOCK(LL_DMA_EnableStream , mock);
//	ACTIVATE_MOCK(LL_USART_EnableDMAReq_RX, mock);
//	ACTIVATE_MOCK(LL_USART_ClearFlag_ORE, mock);
//
//	ACTIVATE_MOCK_RV(LL_USART_DMA_GetRegAddr, mock, expectedSrcAddress);
//
//	Pu_SetupReceive(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_ConfigAddresses, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_SetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_EnableStream, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableDMAReq_RX, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_ClearFlag_ORE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DMA_GetRegAddr, mock), 1);
//}
//
//// Test HandleUsartIrq with a received packet having a correct header checksum
//TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_ok)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	expectedStream = 0;
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_TC, mock, 0);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_TC, mock, 1);
//	ACTIVATE_MOCK(LL_USART_ClearFlag_IDLE, mock);
//	ACTIVATE_MOCK_RV(LL_DMA_GetDataLength, mock, sizeof(struct usartpacket_t) - sizeof(struct usartpacketheader_t) - RoundUpTo4(sizeof(testData)) - sizeof(uint32_t));
//	ACTIVATE_MOCK_RV(Pu_CheckHeader, proxy, 1);
//	ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
//
//	Pu_HandleUsartIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsActiveFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsEnabledIT_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_ClearFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_GetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 1);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//}
//
//// Test HandleUsartIrq with a received packet having a incorrect header checksum
//TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_bad)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	expectedStream = 0;
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_TC, mock, 0);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_TC, mock, 1);
//	ACTIVATE_MOCK(LL_USART_ClearFlag_IDLE, mock);
//	ACTIVATE_MOCK_RV(LL_DMA_GetDataLength, mock, sizeof(struct usartpacket_t) - sizeof(struct usartpacketheader_t) - RoundUpTo4(sizeof(testData)) - sizeof(uint32_t));
//	ACTIVATE_MOCK_RV(Pu_CheckHeader, proxy, 1);
//	ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
//
//	Pu_HandleUsartIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsActiveFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsEnabledIT_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_ClearFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_GetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 1);
//	EXPECT_NE(usartStatus.rxBuffers[0].error, 0);
//	EXPECT_NE(usartStatus.rxBuffers[0].busy, 0);
//}
//
//// Packet reception should continue if the packet is not fully received yet
//TEST_F(PacketUsart, HandleUsartIrq_idle_tooshort)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	expectedStream = 0;
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_TC, mock, 0);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_TC, mock, 1);
//	ACTIVATE_MOCK(LL_USART_ClearFlag_IDLE, mock);
//	ACTIVATE_MOCK_RV(LL_DMA_GetDataLength, mock, sizeof(struct usartpacket_t) - sizeof(struct usartpacketheader_t) - RoundUpTo4(sizeof(testData)) - sizeof(uint32_t) + 1);
//	ACTIVATE_MOCK_RV(Pu_CheckHeader, proxy, 1);
//	ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
//
//	Pu_HandleUsartIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsActiveFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsEnabledIT_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_ClearFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_GetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//}
//
//// Packet reception should continue if the packet is shorter than the packet header
//TEST_F(PacketUsart, HandleUsartIrq_idle_tooshortforheadercheck)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	expectedStream = 0;
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsActiveFlag_TC, mock, 0);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_IDLE, mock, 1);
//	ACTIVATE_MOCK_RV(LL_USART_IsEnabledIT_TC, mock, 1);
//	ACTIVATE_MOCK(LL_USART_ClearFlag_IDLE, mock);
//	ACTIVATE_MOCK_RV(LL_DMA_GetDataLength, mock, sizeof(struct usartpacket_t) - 3);
//	ACTIVATE_MOCK_RV(Pu_CheckHeader, proxy, 1);
//	ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
//
//	Pu_HandleUsartIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsActiveFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_IsEnabledIT_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_ClearFlag_IDLE, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_GetDataLength, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 0);
//	EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_DisableStream, mock), 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//}
//
//// Reception DMA engine transfer complete interrupt is the real verification point of the packet
//// verify that the packet is really checked
//TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrok)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	memset(&fakeDma1, 0, sizeof(fakeDma1));
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//	expectedStream = 0;
//	expectedCrcEnqueueAddress = &usartStatus.rxBuffers[0].packet;
//	expectedCrcLength = RoundUpTo4(usartStatus.rxBuffers[0].packet.header.payloadLength) + sizeof(struct usartpacketheader_t);
//	fakeDma1.LISR = DMA_LISR_TCIF0;
//
//	ACTIVATE_MOCK(Pu_CheckHeader, proxy);
//	ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 0);
//	ACTIVATE_MOCK(Pu_SetupReceive, mock);
//
//	Pu_HandleRxDmaIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Crc_Enqueue, mock), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_SetupReceive, mock), 1);
//	EXPECT_EQ(fakeDma1.LIFCR, DMA_LIFCR_CTCIF0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//}
//
//// In case of the header fails on the end of packet reception error flag should be set
//TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrfail)
//{
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
//
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	memset(&fakeDma1, 0, sizeof(fakeDma1));
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//	expectedStream = 0;
//	expectedCrcEnqueueAddress = &usartStatus.rxBuffers[0].packet;
//	expectedCrcLength = RoundUpTo4(usartStatus.rxBuffers[0].packet.header.payloadLength) + sizeof(struct usartpacketheader_t);
//	fakeDma1.LISR = DMA_LISR_TCIF0;
//
//	ACTIVATE_MOCK(Pu_CheckHeader, proxy);
//	ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 0);
//	ACTIVATE_MOCK(Pu_SetupReceive, mock);
//
//	Pu_HandleRxDmaIrq(&usartStatus);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
//	EXPECT_EQ(MOCK_CALLCOUNT(Crc_Enqueue, mock), 0);
//	EXPECT_EQ(fakeDma1.LIFCR, DMA_LIFCR_CTCIF0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 1);
//	EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
//}
//
//// successfull CRC32 check, CRC32 match, callback should be called, busy flag should be set
//TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_match)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//	memcpy(usartStatus.rxBuffers[0].packet.payload, &testData, sizeof(testData));
//	*(uint32_t*)(usartStatus.rxBuffers[0].packet.payload + RoundUpTo4(sizeof(testData))) = 0xa55a;
//	MOCK_CALLCOUNT(FakePacketReceivedCallback, mock) = 0;
//
//	Pu_RxCrcComputedCallback(&usartStatus.rxBuffers[0], 0xa55a, 1);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(FakePacketReceivedCallback, mock), 1);
//	EXPECT_NE(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
//}
//
//// successfull CRC32 check, CRC32 mismatch, callback should be called,
//// both busy and error flag should be set
//TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_mismatch)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//	memcpy(usartStatus.rxBuffers[0].packet.payload, &testData, sizeof(testData));
//	*(uint32_t*)(usartStatus.rxBuffers[0].packet.payload + RoundUpTo4(sizeof(testData))) = 0xa5a5;
//	MOCK_CALLCOUNT(FakePacketReceivedCallback, mock) = 0;
//
//	Pu_RxCrcComputedCallback(&usartStatus.rxBuffers[0], 0xa55a, 1);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(FakePacketReceivedCallback, mock), 1);
//	EXPECT_NE(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_NE(usartStatus.rxBuffers[0].error, 0);
//}
//
////failed CRC32 check, callback should be called,
//// both busy and error flag should be set
//TEST_F(PacketUsart, HandleRxCrcComputedCallback_failure)
//{
//	Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
//	Pu_SetupReceive(&usartStatus);
//
//	struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
//	memcpy(&usartStatus.rxBuffers[0].packet.header, &fakeHeader, sizeof(fakeHeader));
//	memcpy(usartStatus.rxBuffers[0].packet.payload, &testData, sizeof(testData));
//	*(uint32_t*)(usartStatus.rxBuffers[0].packet.payload + RoundUpTo4(sizeof(testData))) = 0xa5a5;
//	MOCK_CALLCOUNT(FakePacketReceivedCallback, mock) = 0;
//
//	Pu_RxCrcComputedCallback(&usartStatus.rxBuffers[0], 0xa55a, 1);
//
//	EXPECT_EQ(MOCK_CALLCOUNT(FakePacketReceivedCallback, mock), 1);
//	EXPECT_NE(usartStatus.rxBuffers[0].busy, 0);
//	EXPECT_NE(usartStatus.rxBuffers[0].error, 0);
//}
