diff --git a/.cproject b/.cproject index 3a3ba57..94806a0 100644 --- a/.cproject +++ b/.cproject @@ -40,6 +40,7 @@ + @@ -264,7 +268,7 @@ - + diff --git a/App/application.c b/App/application.c new file mode 100644 index 0000000..a652f60 --- /dev/null +++ b/App/application.c @@ -0,0 +1,107 @@ +#include +#include +#include "application.h" +#include "globals.h" +#include "f4ll_c/strutil.h" +#include "diag.h" +#include "f4ll_c/usart_handler.h" +#include "f4ll_c/crc_handler.h" +#include "f4ll_c/console_handler.h" +#include "f4ll_c/memcpy_dma.h" + +#ifndef USE_CPLUSPLUS + +#define PACKAGE_DELAY_MS 0 +#define STATS_DELAY_MS 1000 + +// USART DMA RX TX +// 1 2 2 7 +// 2 1 5 6 +// 3 1 1 3 +// 6 2 1 6 +// console USART +// 4 1 2 4 + +void MainLoop() +{ + uint8_t const text2Send[] __attribute__((aligned(4))) = + "Megszentsegtelenithetetlensegeskedeseitekert\r\n" + "--------------------------------------------\r\n\0\0\0"; + + struct initdata_t { + USART_TypeDef* uart; + DMA_TypeDef* dma; + uint32_t stream_rx; + uint32_t stream_tx; + } static const initdata[] = { + { USART1, DMA2, LL_DMA_STREAM_2, LL_DMA_STREAM_7 }, + { USART2, DMA1, LL_DMA_STREAM_5, LL_DMA_STREAM_6 }, + { USART3, DMA1, LL_DMA_STREAM_1, LL_DMA_STREAM_3 }, + { USART6, DMA2, LL_DMA_STREAM_1, LL_DMA_STREAM_6 }, + }; + + uint32_t lastStatsTick = 0; + uint32_t prevSentTick = 0; + uint8_t statId = 0; + + uint32_t tmp = sizeof(text2Send) - 1; + uint32_t randmask = 0x80000000; + do + if(randmask & tmp) + break; + while((randmask = randmask >> 1)); + randmask -= 1; + + InitCrcStatus(&g_crcStatus, DMA2, LL_DMA_STREAM_4); + + for(uint16_t idx = 0; idx < sizeof(g_uartStatuses) / sizeof(g_uartStatuses[0]); ++idx) { + struct initdata_t const *id = &initdata[idx]; + InitUartStatus(&g_uartStatuses[idx], id->uart, id->dma, id->stream_rx, id->stream_tx, &g_crcStatus, NULL, NULL); + memcpy(GetTxBuffer(&g_uartStatuses[idx]), text2Send, sizeof(text2Send) -1); + } + + InitDmaInfo(&g_ConsoleTxDmaInfo, CONSOLE_DMA_ENGINE, CONSOLE_TX_DMA_STREAM); + LL_DMA_EnableIT_TC(g_ConsoleTxDmaInfo.dma, g_ConsoleTxDmaInfo.stream); + + InitMemcpyDma(MEMCPY_DMA_ENGINE, MEMCPY_DMA_STREAM); + + lastStatsTick = HAL_GetTick(); + + for(uint16_t idx = 0; idx < sizeof(g_uartStatuses) / sizeof(g_uartStatuses[0]); ++idx) + SetupReceive(&g_uartStatuses[idx]); + + for(;;) { + uint32_t tick = HAL_GetTick(); + uint8_t send = PACKAGE_DELAY_MS ? (tick - prevSentTick > PACKAGE_DELAY_MS) : 1; + if(send) + prevSentTick += PACKAGE_DELAY_MS; + + for(uint16_t idx = 0; idx < sizeof(g_uartStatuses) / sizeof(g_uartStatuses[0]); ++idx) { + if(!g_uartStatuses[idx].txBuffer.busy && send) { + DIAG_ENTER_BUSY(); + PostPacket(&g_uartStatuses[idx], text2Send, sizeof(text2Send) - 1 - (rand() & randmask), &g_crcStatus); + DIAG_EXIT_BUSY(); + } + for(uint16_t rIdx = 0; rIdx < 2; ++rIdx) + if(g_uartStatuses[idx].rxBuffers[rIdx].busy || g_uartStatuses[idx].rxBuffers[rIdx].error) { + DIAG_ENTER_BUSY(); + ConsumePacket(&g_uartStatuses[idx], rIdx); + DIAG_EXIT_BUSY(); + } + } + if(tick - lastStatsTick > STATS_DELAY_MS) { + PrintStats((char*)g_statsBuf, statId, &g_uartStatuses[statId].stats, UART4, &g_ConsoleTxDmaInfo); + lastStatsTick += STATS_DELAY_MS; + ++statId; + if(statId >= USARTCOUNT) + statId = 0; + } + uint32_t ein = LL_GPIO_ReadInputPort(KEY1_GPIO_Port); + if(!(ein & KEY1_Pin)) { + void (*fptr)(void) = (void (*)(void))(void*)0xa0000000; + fptr(); + } + } +} + +#endif // USE_CPLUSPLUS diff --git a/App/application.cpp b/App/application_cpp.cpp similarity index 98% rename from App/application.cpp rename to App/application_cpp.cpp index 1509b8e..a4f49ae 100644 --- a/App/application.cpp +++ b/App/application_cpp.cpp @@ -4,6 +4,8 @@ * Created on: Oct 28, 2019 * Author: abody */ +#ifdef USE_CPLUSPLUS + #include #include #include "f4ll/ll_hsusart.h" @@ -96,3 +98,5 @@ extern "C" void MainLoop() // } } } + +#endif // USE_CPLUSPLUS diff --git a/App/globals.c b/App/globals.c index edf988c..8e4caac 100644 --- a/App/globals.c +++ b/App/globals.c @@ -9,7 +9,7 @@ USARTSTATUS g_uartStatuses[USARTCOUNT]; -CRCSTATUS g_crcStatus; +struct crcstatus_t g_crcStatus; DMAINFO g_ConsoleTxDmaInfo; uint8_t g_statsBuf[256]; diff --git a/App/globals.h b/App/globals.h index b6b1f29..27771e0 100644 --- a/App/globals.h +++ b/App/globals.h @@ -16,7 +16,7 @@ extern USARTSTATUS g_uartStatuses[USARTCOUNT]; -extern CRCSTATUS g_crcStatus; +extern struct crcstatus_t g_crcStatus; extern DMAINFO g_ConsoleTxDmaInfo; extern uint8_t g_statsBuf[256]; diff --git a/Src/stm32f4xx_it.c b/Src/stm32f4xx_it.c index 49a52d8..5784346 100644 --- a/Src/stm32f4xx_it.c +++ b/Src/stm32f4xx_it.c @@ -26,17 +26,21 @@ extern "C" { #include "stm32f4xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#ifndef USE_CPLUSPLUS #include "f4ll_c/usart_handler.h" #include "f4ll_c/crc_handler.h" #include "f4ll_c/console_handler.h" #include "f4ll_c/memcpy_dma.h" +#endif #include "globals.h" #include "diag.h" } +#ifdef USE_CPLUSPLUS #include "globals_cpp.h" #include "f4ll/ll_memcpydma.h" #include "f4ll/ll_consolehandler.h" +#endif extern "C" { @@ -224,7 +228,11 @@ void SysTick_Handler(void) void DMA1_Stream1_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_UsartCore::HandleRxDmaIrq(g_usarts[USART3_OFFSET]); +#else + HandleUsartRxDmaIrq(&g_uartStatuses[USART3_OFFSET]); +#endif /* USER CODE END DMA1_Stream1_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ @@ -252,7 +260,11 @@ void DMA1_Stream2_IRQHandler(void) void DMA1_Stream3_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleTxDmaIrq(g_usarts[USART3_OFFSET]); +#else + HandleUsartTxDmaIrq(&g_uartStatuses[USART3_OFFSET]); +#endif /* USER CODE END DMA1_Stream3_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */ @@ -266,7 +278,11 @@ void DMA1_Stream3_IRQHandler(void) void DMA1_Stream4_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_ConsoleHandler::HandleTxDmaIrq(&f4ll::LL_ConsoleHandler::Instance()); +#else + HandleConsoleUsartTxDmaIrq(&g_ConsoleTxDmaInfo, UART4); +#endif /* USER CODE END DMA1_Stream4_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream4_IRQn 1 */ @@ -280,7 +296,11 @@ void DMA1_Stream4_IRQHandler(void) void DMA1_Stream5_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream5_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleRxDmaIrq(g_usarts[USART2_OFFSET]); +#else + HandleUsartRxDmaIrq(&g_uartStatuses[USART2_OFFSET]); +#endif /* USER CODE END DMA1_Stream5_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream5_IRQn 1 */ @@ -294,7 +314,11 @@ void DMA1_Stream5_IRQHandler(void) void DMA1_Stream6_IRQHandler(void) { /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleTxDmaIrq(g_usarts[USART2_OFFSET]); +#else + HandleUsartTxDmaIrq(&g_uartStatuses[USART2_OFFSET]); +#endif /* USER CODE END DMA1_Stream6_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */ @@ -334,8 +358,11 @@ void SPI2_IRQHandler(void) void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleUsartIrq(g_usarts[USART1_OFFSET]); - // _HandleUsartIrq(); +#else + HandleUsartIrq(&g_uartStatuses[USART1_OFFSET]); +#endif /* USER CODE END USART1_IRQn 0 */ /* USER CODE BEGIN USART1_IRQn 1 */ @@ -348,7 +375,11 @@ void USART1_IRQHandler(void) void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleUsartIrq(g_usarts[USART2_OFFSET]); +#else + HandleUsartIrq(&g_uartStatuses[USART2_OFFSET]); +#endif /* USER CODE END USART2_IRQn 0 */ /* USER CODE BEGIN USART2_IRQn 1 */ @@ -361,7 +392,11 @@ void USART2_IRQHandler(void) void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleUsartIrq(g_usarts[USART3_OFFSET]); +#else + HandleUsartIrq(&g_uartStatuses[USART3_OFFSET]); +#endif /* USER CODE END USART3_IRQn 0 */ /* USER CODE BEGIN USART3_IRQn 1 */ @@ -374,7 +409,11 @@ void USART3_IRQHandler(void) void UART4_IRQHandler(void) { /* USER CODE BEGIN UART4_IRQn 0 */ +#ifdef USE_CPLUSPLUS + f4ll::LL_ConsoleHandler::HandleUsartIrq(&f4ll::LL_ConsoleHandler::Instance()); +#else HandleConsoleUsartIrq(UART4); +#endif /* USER CODE END UART4_IRQn 0 */ /* USER CODE BEGIN UART4_IRQn 1 */ @@ -401,7 +440,11 @@ void DMA2_Stream0_IRQHandler(void) void DMA2_Stream1_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleRxDmaIrq(g_usarts[USART6_OFFSET]); +#else + HandleUsartRxDmaIrq(&g_uartStatuses[USART6_OFFSET]); +#endif /* USER CODE END DMA2_Stream1_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */ @@ -415,7 +458,11 @@ void DMA2_Stream1_IRQHandler(void) void DMA2_Stream2_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleRxDmaIrq(g_usarts[USART1_OFFSET]); +#else + HandleUsartRxDmaIrq(&g_uartStatuses[USART1_OFFSET]); +#endif /* USER CODE END DMA2_Stream2_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */ @@ -429,8 +476,11 @@ void DMA2_Stream2_IRQHandler(void) void DMA2_Stream3_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_MemcpyDma::Instance().DmaTransferCompleted(); - +#else + HandleMemcpyDmaIrq(); +#endif /* USER CODE END DMA2_Stream3_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */ @@ -444,7 +494,11 @@ void DMA2_Stream3_IRQHandler(void) void DMA2_Stream4_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream4_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_CrcHandler::Instance().DmaTransferCompleted(); +#else + HandleCrcDmaIrq(&g_crcStatus); +#endif /* USER CODE END DMA2_Stream4_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream4_IRQn 1 */ @@ -472,7 +526,11 @@ void DMA2_Stream5_IRQHandler(void) void DMA2_Stream6_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream6_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleTxDmaIrq(g_usarts[USART6_OFFSET]); +#else + HandleUsartTxDmaIrq(&g_uartStatuses[USART6_OFFSET]); +#endif /* USER CODE END DMA2_Stream6_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream6_IRQn 1 */ @@ -486,7 +544,11 @@ void DMA2_Stream6_IRQHandler(void) void DMA2_Stream7_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream7_IRQn 0 */ +#ifdef USE_CPLUSPLUS f4ll::LL_HsUsart::HandleTxDmaIrq(g_usarts[USART1_OFFSET]); +#else + HandleUsartTxDmaIrq(&g_uartStatuses[USART1_OFFSET]); +#endif /* USER CODE END DMA2_Stream7_IRQn 0 */ /* USER CODE BEGIN DMA2_Stream7_IRQn 1 */ @@ -500,7 +562,11 @@ void DMA2_Stream7_IRQHandler(void) void USART6_IRQHandler(void) { /* USER CODE BEGIN USART6_IRQn 0 */ - f4ll::LL_HsUsart::HandleUsartIrq(g_usarts[USART6_OFFSET]); +#ifdef USE_CPLUSPLUS + f4ll::LL_HsUsart::HandleUsartIrq(g_usarts[USART6_OFFSET]); +#else + HandleUsartIrq(&g_uartStatuses[USART6_OFFSET]); +#endif /* USER CODE END USART6_IRQn 0 */ /* USER CODE BEGIN USART6_IRQn 1 */ diff --git a/components/f4ll/inc/ll_crchandler.h b/components/f4ll/inc/ll_crchandler.h index d8fd54f..0b723e7 100644 --- a/components/f4ll/inc/ll_crchandler.h +++ b/components/f4ll/inc/ll_crchandler.h @@ -23,8 +23,8 @@ class LL_CrcHandler : public Singleton public: struct ICallback { - virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio) = 0; - virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, int prio) = 0; + virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, uint8_t task) = 0; + virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, uint8_t task) = 0; }; class SlotBase @@ -39,8 +39,9 @@ public: }; private: - SlotBase *m_next = nullptr; - uint8_t m_taskCount; + SlotBase *m_next = nullptr; + uint8_t m_taskCount; + virtual CrcTask& operator[](int index) = 0; protected: @@ -49,7 +50,6 @@ public: SlotBase(SlotBase const &other) = delete; }; - // DON't try this at home! we "extend" LL_CrcHandler::m_tasks this way template class Slot : public SlotBase { public: @@ -61,12 +61,12 @@ public: }; void AttachSlot(SlotBase &slot); - bool Enqueue(SlotBase &slot, uint8_t prio, void const *address, uint16_t len, ICallback *cb, uintptr_t cbParam); - uint32_t Compute(SlotBase &slot, uint8_t prio, void const *address, uint16_t len); + bool Enqueue(SlotBase &slot, uint8_t task, void const *address, uint16_t len, ICallback *cb, uintptr_t cbParam); + uint32_t Compute(SlotBase &slot, uint8_t task, void const *address, uint16_t len); - bool IsActive(SlotBase &slot, uint8_t prio) const; - bool IsQueued(SlotBase &slot, uint8_t prio) const; - bool IsRunning(SlotBase &slot, uint8_t prio) const; + bool IsActive(SlotBase &slot, uint8_t task) const; + bool IsQueued(SlotBase &slot, uint8_t task) const; + bool IsRunning(SlotBase &slot, uint8_t task) const; void DmaTransferCompleted(void); @@ -75,12 +75,12 @@ private: friend void ::_HandleCrcDmaIrq(void); void StartNextTask(void); - void WaitResults(SlotBase &slot, uint8_t prio) const; + void WaitResults(SlotBase &slot, uint8_t task) const; - LL_DmaHelper m_dma; + LL_DmaHelper m_dma; SlotBase * volatile m_firstSlot = nullptr; SlotBase * volatile m_activeSlot = nullptr; - int volatile m_activePrio; + int volatile m_activeTask; }; diff --git a/components/f4ll/inc/ll_hsusart.h b/components/f4ll/inc/ll_hsusart.h index 4af8b75..9ca09eb 100644 --- a/components/f4ll/inc/ll_hsusart.h +++ b/components/f4ll/inc/ll_hsusart.h @@ -52,8 +52,8 @@ public: }; // LL_CRCHandler::ICallback interface functions - virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio); - virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, int prio); + virtual void CrcSucceeded(uintptr_t callbackParam, uint32_t crc, uint8_t task); + virtual void CrcFailed(uintptr_t callbackParam, uint32_t crc, uint8_t task); // LL_UsartCore pure virtual function implementations virtual void ReceiverIdle(void); diff --git a/components/f4ll/src/ll_crchandler.cpp b/components/f4ll/src/ll_crchandler.cpp index c0307ce..35a96fd 100644 --- a/components/f4ll/src/ll_crchandler.cpp +++ b/components/f4ll/src/ll_crchandler.cpp @@ -26,31 +26,31 @@ void LL_CrcHandler::AttachSlot(SlotBase &slot) task.m_callback = nullptr; task.m_callbackParam = 0; } - slot.m_next = m_firstSlot; uint32_t prim = __get_PRIMASK(); __disable_irq(); + slot.m_next = m_firstSlot; m_firstSlot = &slot; __set_PRIMASK(prim); } -bool LL_CrcHandler::Enqueue(SlotBase &slot, uint8_t prio, void const *address, uint16_t len, ICallback *cb, uintptr_t cbParam) +bool LL_CrcHandler::Enqueue(SlotBase &slot, uint8_t task, void const *address, uint16_t len, ICallback *cb, uintptr_t cbParam) { uint32_t prim = __get_PRIMASK(); bool immediate; - // TODO: do we need sanity check here? (is slot attached, is prio in range, etc...?) + // TODO: do we need sanity check here? (is slot attached, is task in range, etc...?) - while(IsActive(slot,prio)); + while(IsActive(slot,task)); __disable_irq(); immediate = m_activeSlot == nullptr; - slot[prio].m_address = (!immediate) ? address : nullptr; - slot[prio].m_wordCount = (len+3)/4; - slot[prio].m_callback = cb; - slot[prio].m_callbackParam = cbParam; + slot[task].m_address = (!immediate) ? address : nullptr; + slot[task].m_wordCount = (len+3)/4; + slot[task].m_callback = cb; + slot[task].m_callbackParam = cbParam; if(immediate) { m_activeSlot = &slot; - m_activePrio = prio; + m_activeTask = task; } __set_PRIMASK(prim); @@ -63,19 +63,19 @@ bool LL_CrcHandler::Enqueue(SlotBase &slot, uint8_t prio, void const *address, u return immediate; } -bool LL_CrcHandler::IsActive(SlotBase &slot, uint8_t prio) const +bool LL_CrcHandler::IsActive(SlotBase &slot, uint8_t task) const { - return prio < slot.m_taskCount && slot[prio].m_wordCount != 0; + return task < slot.m_taskCount && slot[task].m_wordCount != 0; } -bool LL_CrcHandler::IsQueued(SlotBase &slot, uint8_t prio) const +bool LL_CrcHandler::IsQueued(SlotBase &slot, uint8_t task) const { - return prio < slot.m_taskCount && slot[prio].m_address != nullptr; + return task < slot.m_taskCount && slot[task].m_address != nullptr; } -bool LL_CrcHandler::IsRunning(SlotBase &slot, uint8_t prio) const +bool LL_CrcHandler::IsRunning(SlotBase &slot, uint8_t task) const { - return prio < slot.m_taskCount && slot[prio].m_wordCount && ! slot[prio].m_address; + return task < slot.m_taskCount && slot[task].m_wordCount && ! slot[task].m_address; } void LL_CrcHandler::DmaTransferCompleted(void) @@ -84,25 +84,25 @@ void LL_CrcHandler::DmaTransferCompleted(void) * m_dma.GetIfcReg() = m_dma.GetTcMask(); LL_DMA_DisableStream(m_dma.GetDma(), m_dma.GetStream()); if(m_activeSlot) { - if((*m_activeSlot)[m_activePrio].m_callback) - (*m_activeSlot)[m_activePrio].m_callback->CrcSucceeded((*m_activeSlot)[m_activePrio].m_callbackParam, CRC->DR, m_activePrio); - else if((*m_activeSlot)[m_activePrio].m_callbackParam) - *reinterpret_cast((*m_activeSlot)[m_activePrio].m_callbackParam) = CRC->DR; + if((*m_activeSlot)[m_activeTask].m_callback) + (*m_activeSlot)[m_activeTask].m_callback->CrcSucceeded((*m_activeSlot)[m_activeTask].m_callbackParam, CRC->DR, m_activeTask); + else if((*m_activeSlot)[m_activeTask].m_callbackParam) + *reinterpret_cast((*m_activeSlot)[m_activeTask].m_callbackParam) = CRC->DR; } } else if(*m_dma.GetIsReg() & m_dma.GetTeMask()) { // DMA transfer error *m_dma.GetIfcReg() = m_dma.GetTeMask(); LL_DMA_DisableStream(m_dma.GetDma(), m_dma.GetStream()); if(m_activeSlot) { - if((*m_activeSlot)[m_activePrio].m_callback) - (*m_activeSlot)[m_activePrio].m_callback->CrcFailed((*m_activeSlot)[m_activePrio].m_callbackParam, CRC->DR, m_activePrio); - else if((*m_activeSlot)[m_activePrio].m_callbackParam) - *reinterpret_cast((*m_activeSlot)[m_activePrio].m_callbackParam) = -1; + if((*m_activeSlot)[m_activeTask].m_callback) + (*m_activeSlot)[m_activeTask].m_callback->CrcFailed((*m_activeSlot)[m_activeTask].m_callbackParam, CRC->DR, m_activeTask); + else if((*m_activeSlot)[m_activeTask].m_callbackParam) + *reinterpret_cast((*m_activeSlot)[m_activeTask].m_callbackParam) = -1; } } - (*m_activeSlot)[m_activePrio].m_callback = nullptr; - (*m_activeSlot)[m_activePrio].m_callbackParam = 0; - (*m_activeSlot)[m_activePrio].m_wordCount = 0; + (*m_activeSlot)[m_activeTask].m_callback = nullptr; + (*m_activeSlot)[m_activeTask].m_callbackParam = 0; + (*m_activeSlot)[m_activeTask].m_wordCount = 0; StartNextTask(); } @@ -118,7 +118,7 @@ void LL_CrcHandler::StartNextTask(void) if(index < slot->m_taskCount) { if((*slot)[index].m_address) { m_activeSlot = slot; - m_activePrio = index; + m_activeTask = index; CRC->CR = 1; LL_DMA_SetM2MSrcAddress(m_dma.GetDma(), m_dma.GetStream(), reinterpret_cast((*slot)[index].m_address)); LL_DMA_SetDataLength(m_dma.GetDma(), m_dma.GetStream(), (*slot)[index].m_wordCount); @@ -137,19 +137,19 @@ void LL_CrcHandler::StartNextTask(void) } -void LL_CrcHandler::WaitResults(SlotBase &slot, uint8_t prio) const +void LL_CrcHandler::WaitResults(SlotBase &slot, uint8_t task) const { - while(IsQueued(slot, prio)); - while(IsActive(slot, prio)); + while(IsQueued(slot, task)); + while(IsActive(slot, task)); } uint32_t LL_CrcHandler::Compute( - SlotBase &slot, uint8_t prio, void const *address, uint16_t len) + SlotBase &slot, uint8_t task, void const *address, uint16_t len) { uint32_t result; - Enqueue(slot, prio, address, len, nullptr, reinterpret_cast(&result)); - while(IsActive(slot, prio)); + Enqueue(slot, task, address, len, nullptr, reinterpret_cast(&result)); + while(IsActive(slot, task)); return result; } diff --git a/components/f4ll/src/ll_hsusart.cpp b/components/f4ll/src/ll_hsusart.cpp index f96a965..b180742 100644 --- a/components/f4ll/src/ll_hsusart.cpp +++ b/components/f4ll/src/ll_hsusart.cpp @@ -208,7 +208,7 @@ void LL_HsUsart::SwitchRxBuffers(void) } -void LL_HsUsart::CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio) +void LL_HsUsart::CrcSucceeded(uintptr_t callbackParam, uint32_t crc, uint8_t task) { Buffer &buf(m_rxBuffers[static_cast(callbackParam)]); @@ -223,7 +223,7 @@ void LL_HsUsart::CrcSucceeded(uintptr_t callbackParam, uint32_t crc, int prio) } -void LL_HsUsart::CrcFailed(uintptr_t callbackParam, uint32_t crc, int prio) +void LL_HsUsart::CrcFailed(uintptr_t callbackParam, uint32_t crc, uint8_t task) { Buffer &buf(m_rxBuffers[static_cast(callbackParam)]); buf.busy = buf.error = true; diff --git a/components/f4ll_c/inc/crc_handler.h b/components/f4ll_c/inc/crc_handler.h index a980cce..4777e8f 100644 --- a/components/f4ll_c/inc/crc_handler.h +++ b/components/f4ll_c/inc/crc_handler.h @@ -20,34 +20,48 @@ #define CRCTASKCOUNT 2 #endif -typedef struct { - DMAINFO dmaInfo; - volatile uint8_t activeSlot; - struct crctask_t { - void *address; - uint16_t wordCount; - void (*callback)(void*, uint32_t, uint8_t); - void *callbackParam; - } volatile crcTasks[CRCTASKCOUNT]; -} CRCSTATUS; +struct crcslottask_t { + void *address; + uint16_t wordCount; + void (*callback)(void*, uint32_t, uint8_t); + void *callbackParam; +}; -void InitCrcStatus(CRCSTATUS *status, DMA_TypeDef *dma, uint32_t stream); -static inline uint8_t GetActiveSlot(CRCSTATUS *status) { - return status->activeSlot; +struct crcslotlistitem_t { + uint16_t count; + struct crcslotlistitem_t *next; + struct crcslottask_t *tasks; +}; + +struct crcstatus_t { + DMAINFO dmaInfo; + volatile struct crcslotlistitem_t *activeSlot; + volatile uint8_t activeTask; + + struct crcslotlistitem_t *first; +}; + +void InitCrcStatus(struct crcstatus_t *status, DMA_TypeDef *dma, uint32_t stream); + +uint8_t GetActiveSlot(struct crcslotlistitem_t **slot_out, struct crcstatus_t *status); + +static inline uint8_t IsSlotQueued(struct crcslotlistitem_t *slot, uint8_t task) { + return slot->tasks[task].address != NULL; } -static inline uint8_t IsSlotQueued(CRCSTATUS *status, uint8_t slot) { - return status->crcTasks[slot].address != NULL; + +static inline uint8_t IsSlotActive(struct crcslotlistitem_t *slot, uint8_t task) { + return slot->tasks[task].callback != NULL || slot->tasks[task].callbackParam != NULL; } -static inline uint8_t IsSlotActive(CRCSTATUS *status, uint8_t slot) { - return status->crcTasks[slot].callback != NULL || status->crcTasks[slot].callbackParam != NULL; -} -uint8_t EnqueueCrcTask(CRCSTATUS *crcStatus, uint8_t slot, uint8_t *address, uint16_t len, - void (*callback)(void*, uint32_t, uint8_t), void* callbackParam); -void WaitCrcResults(CRCSTATUS *status, uint8_t slot); -uint32_t ComputeCrc(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16_t len); -void ComputeCrcAsync(CRCSTATUS *status, uint8_t slot, + +void AttachCrcTask(struct crcstatus_t *status, struct crcslotlistitem_t *slot, struct crcslottask_t *tasks, uint8_t taskCount); + +uint8_t EnqueueCrcTask(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, + uint8_t *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam); +void WaitCrcResults(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task); +uint32_t ComputeCrc(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, uint8_t *address, uint16_t len); +void ComputeCrcAsync(struct crcstatus_t *status, uint8_t slot, uint8_t *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam); -void HandleCrcDmaIrq(CRCSTATUS *status); +void HandleCrcDmaIrq(struct crcstatus_t *status); #endif /* CRC_HANDLER_H_ */ diff --git a/components/f4ll_c/inc/usart_handler.h b/components/f4ll_c/inc/usart_handler.h index 77b3021..32e2f5c 100644 --- a/components/f4ll_c/inc/usart_handler.h +++ b/components/f4ll_c/inc/usart_handler.h @@ -21,15 +21,15 @@ typedef void (*PACKETRECEIVEDCALLBACK)(void *userParam, struct usart_buffer *buf void InitUartStatus( USARTSTATUS *st, USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, - CRCSTATUS *crcStatus, uint8_t rxCrcSlot, uint8_t txCrcSlot, + struct crcstatus_t *crcStatus, PACKETRECEIVEDCALLBACK packetReceivedCallback, void * packetReceivedCallbackParam); uint8_t* GetTxBuffer(USARTSTATUS *status); -uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, CRCSTATUS *crcStatus); +uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, struct crcstatus_t *crcStatus); void SetupReceive(USARTSTATUS *status); void SetupTransmit(USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length); -void ConsumePacket(USARTSTATUS *status, uint8_t packetIndex, CRCSTATUS *crcStatus); +void ConsumePacket(USARTSTATUS *status, uint8_t packetIndex); void HandleUsartRxDmaIrq(USARTSTATUS *status); void HandleUsartTxDmaIrq(USARTSTATUS *status); @@ -82,13 +82,14 @@ struct _usart_status { USART_TypeDef *usart; DMAINFO rxDmaInfo; DMAINFO txDmaInfo; - CRCSTATUS *crcStatus; + struct crcstatus_t *crcStatus; + struct crcslotlistitem_t crcSlot; + struct crcslottask_t crcTasks[2]; + uint8_t rxSerial; uint8_t txSerial; struct usart_stats stats; uint8_t activeRxBuf; - uint8_t rxCrcSlot; - uint8_t txCrcSlot; PACKETRECEIVEDCALLBACK packetReceivedCallback; void *packetReceivedCallbacParam; struct usart_buffer txBuffer; diff --git a/components/f4ll_c/src/crc_handler.c b/components/f4ll_c/src/crc_handler.c index e6bced4..33639fe 100644 --- a/components/f4ll_c/src/crc_handler.c +++ b/components/f4ll_c/src/crc_handler.c @@ -27,29 +27,57 @@ #endif -void InitCrcStatus(CRCSTATUS *st, DMA_TypeDef *dma, uint32_t stream) +void InitCrcStatus(struct crcstatus_t *st, DMA_TypeDef *dma, uint32_t stream) { InitDmaInfo(&st->dmaInfo, dma, stream); LL_DMA_EnableIT_TC(dma, stream); LL_DMA_EnableIT_TE(dma, stream); LL_DMA_SetM2MDstAddress(dma, stream, (uint32_t)&CRC->DR); - st->activeSlot = 0xff; - memset((void*)st->crcTasks, 0, sizeof(st->crcTasks)); + st->activeSlot = NULL; + st->first = NULL; } -uint8_t EnqueueCrcTask(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16_t len, - void (*callback)(void*, uint32_t, uint8_t), void* callbackParam) +void AttachCrcTask(struct crcstatus_t *status, struct crcslotlistitem_t *slot, struct crcslottask_t *tasks, uint8_t taskCount) +{ + slot->count = taskCount; + slot->tasks = tasks; + memset(tasks, 0, sizeof(*tasks)*taskCount); + + uint32_t prim = __get_PRIMASK(); + __disable_irq(); + slot->next = status->first; + status->first = slot; + __set_PRIMASK(prim); +} + +uint8_t GetActiveSlot(struct crcslotlistitem_t **slot_out, struct crcstatus_t *status) +{ + uint8_t ret; + + uint32_t prim = __get_PRIMASK(); + + __disable_irq(); + ret = status->activeTask; + if(slot_out) + *slot_out = (struct crcslotlistitem_t *) status->activeSlot; + __set_PRIMASK(prim); + return ret; +} + + +uint8_t EnqueueCrcTask(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, + uint8_t *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam) { uint32_t prim = __get_PRIMASK(); uint16_t need_start; while(status->activeSlot == slot); __disable_irq(); - need_start = (status->activeSlot == 0xff); - status->crcTasks[slot].address = need_start ? NULL : address; - status->crcTasks[slot].wordCount = (len+3)/4; - status->crcTasks[slot].callback = callback; - status->crcTasks[slot].callbackParam = callbackParam; + need_start = (status->activeSlot == NULL); + slot->tasks[task].address = need_start ? NULL : address; + slot->tasks[task].wordCount = (len+3)/4; + slot->tasks[task].callback = callback; + slot->tasks[task].callbackParam = callbackParam; if(need_start) status->activeSlot = slot; __set_PRIMASK(prim); @@ -64,46 +92,62 @@ uint8_t EnqueueCrcTask(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16 return need_start; } -void WaitCrcResults(CRCSTATUS *status, uint8_t slot) +void WaitCrcResults(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task) { - while(IsSlotQueued(status, slot)); - while(GetActiveSlot(status) == slot); + struct crcslotlistitem_t *slotQueued; + + while(IsSlotQueued(slot, task)); + while(GetActiveSlot(&slotQueued, status) == task && slotQueued == slot); } -uint32_t ComputeCrc(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16_t len) + +uint32_t ComputeCrc(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, uint8_t *address, uint16_t len) { uint32_t result; - EnqueueCrcTask(status, slot, address, len, NULL, &result); - while(status->crcTasks[slot].callbackParam); + EnqueueCrcTask(status, slot, task, address, len, NULL, &result); + while(slot->tasks[task].callbackParam); return result; } -void StartNextCrcTask(CRCSTATUS *status) -{ - uint16_t slot; - for(slot = 0; slot < CRCTASKCOUNT; ++slot) - if(status->crcTasks[slot].address) { - status->activeSlot = slot; - CRC->CR = 1; - LL_DMA_SetM2MSrcAddress(status->dmaInfo.dma, status->dmaInfo.stream, (uint32_t)status->crcTasks[slot].address); - LL_DMA_SetDataLength(status->dmaInfo.dma, status->dmaInfo.stream, status->crcTasks[slot].wordCount); - DIAG_CRC_CALC_START(); - LL_DMA_EnableStream(status->dmaInfo.dma, status->dmaInfo.stream); - status->crcTasks[slot].address = NULL; // marking as started - return; - } - status->activeSlot = 0xff; +static void StartNextCrcTask(struct crcstatus_t *status) +{ + int stillMore; + uint8_t index = 0; + + do { + struct crcslotlistitem_t *slot = status->first; + stillMore = 0; + while(slot) { + if(index < slot->count) { + if(slot->tasks[index].address) { + status->activeSlot = slot; + status->activeTask = index; + CRC->CR = 1; + LL_DMA_SetM2MSrcAddress(status->dmaInfo.dma, status->dmaInfo.stream, (uint32_t)slot->tasks[index].address); + LL_DMA_SetDataLength(status->dmaInfo.dma, status->dmaInfo.stream, slot->tasks[index].wordCount); + LL_DMA_EnableStream(status->dmaInfo.dma, status->dmaInfo.stream); + slot->tasks[index].address = NULL; // marking as started + return; + } + if(index + 1 < slot->count) + stillMore = 1; + } + slot = slot->next; + } + ++index; + } while(stillMore); + status->activeSlot = NULL; } -void HandleCrcDmaIrq(CRCSTATUS *status) +void HandleCrcDmaIrq(struct crcstatus_t *status) { DIAG_INTERRUPT_IN(); if(*status->dmaInfo.isReg & status->dmaInfo.tcMask) { // DMA transfer complete *status->dmaInfo.ifcReg = status->dmaInfo.tcMask; LL_DMA_DisableStream(status->dmaInfo.dma, status->dmaInfo.stream); - if(status->activeSlot != 0xff) { - struct crctask_t *tsk = (struct crctask_t *)&status->crcTasks[status->activeSlot]; + if(status->activeSlot) { + struct crcslottask_t *tsk = &status->activeSlot->tasks[status->activeTask]; if(tsk->callback) tsk->callback(tsk->callbackParam, CRC->DR, 1); else if(tsk->callbackParam) @@ -116,8 +160,8 @@ void HandleCrcDmaIrq(CRCSTATUS *status) else if(*status->dmaInfo.isReg & status->dmaInfo.teMask) { *status->dmaInfo.ifcReg = status->dmaInfo.teMask; LL_DMA_DisableStream(status->dmaInfo.dma, status->dmaInfo.stream); - if(status->activeSlot != 0xff) { - struct crctask_t *tsk = (struct crctask_t *)&status->crcTasks[status->activeSlot]; + if(status->activeSlot) { + struct crcslottask_t *tsk = &status->activeSlot->tasks[status->activeTask]; if(tsk->callback) tsk->callback(tsk->callbackParam, CRC->DR, 0); else if(tsk->callbackParam) diff --git a/components/f4ll_c/src/usart_handler.c b/components/f4ll_c/src/usart_handler.c index 2a0e04b..47562fe 100644 --- a/components/f4ll_c/src/usart_handler.c +++ b/components/f4ll_c/src/usart_handler.c @@ -33,7 +33,7 @@ static inline uint32_t RoundUpTo4(uint32_t inp) void InitUartStatus( USARTSTATUS *st, USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, - CRCSTATUS *crcStatus, uint8_t rxCrcSlot, uint8_t txCrcSlot, + struct crcstatus_t *crcStatus, PACKETRECEIVEDCALLBACK packetReceivedCallback, void * packetReceivedCallbackParam) { st->usart = usart; @@ -57,8 +57,7 @@ void InitUartStatus( st->txSerial = 0; st->activeRxBuf = 0; st->crcStatus = crcStatus; - st->txCrcSlot = txCrcSlot; - st->rxCrcSlot = rxCrcSlot; + AttachCrcTask(crcStatus, &st->crcSlot, st->crcTasks, 2); memset(&st->stats, 0, sizeof(st->stats)); LL_DMA_EnableIT_TC(dma, stream_rx); @@ -92,7 +91,7 @@ static inline uint8_t CheckHeader(USARTPACKET *packet) } -uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, CRCSTATUS *crcStatus) +uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, struct crcstatus_t *crcStatus) { if(length > 256) return 1; @@ -112,9 +111,9 @@ uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, status->txBuffer.requestedLength = sizeof(USARTPACKETHEADER) + payloadLength + sizeof(uint32_t); // +4 for the hash status->txBuffer.busy = 1; status->txBuffer.error = 0; - EnqueueCrcTask(crcStatus, status->txCrcSlot, status->txBuffer.packet.payload, length, + EnqueueCrcTask(status->crcStatus, &status->crcSlot, 0, status->txBuffer.packet.payload, length, NULL, (uint32_t*)(status->txBuffer.packet.payload + payloadLength)); - while(IsSlotQueued(crcStatus, status->txCrcSlot)); + while(IsSlotQueued(&status->crcSlot, 0)); SetupTransmit(status->usart, status->txDmaInfo.dma, status->txDmaInfo.stream, &status->txBuffer.packet, status->txBuffer.requestedLength); StatsIncSent(&status->stats); @@ -136,7 +135,7 @@ void SetupReceive(USARTSTATUS *status) } -void ConsumePacket(USARTSTATUS *status, uint8_t packetIndex, CRCSTATUS *crcStatus) +void ConsumePacket(USARTSTATUS *status, uint8_t packetIndex) { struct usart_buffer *buffer = &status->rxBuffers[packetIndex]; if(buffer->busy) { @@ -184,7 +183,7 @@ void HandleUsartRxDmaIrq(USARTSTATUS *status) if(*status->rxDmaInfo.isReg & status->rxDmaInfo.tcMask) { *status->rxDmaInfo.ifcReg = status->rxDmaInfo.tcMask; if(CheckHeader(&status->rxBuffers[status->activeRxBuf].packet)) - EnqueueCrcTask(status->crcStatus, status->rxCrcSlot, + EnqueueCrcTask(status->crcStatus, &status->crcSlot, 1, status->rxBuffers[status->activeRxBuf].packet.payload, status->rxBuffers[status->activeRxBuf].packet.header.payloadLength +1, RxCrcComputedCallback, &status->rxBuffers[status->activeRxBuf]);