From e8cff640ac8c789cd34fdad9948dbc59705adf10 Mon Sep 17 00:00:00 2001 From: abody Date: Fri, 18 Oct 2019 13:55:10 +0200 Subject: [PATCH] Fine-tuning "libs" API --- app/application.c | 8 +- app/application.h | 1 - app/config.h | 4 +- app/globals.c | 4 +- app/globals.h | 4 +- app/platform/crc_ll.h | 6 ++ app/platform/dma_ll.h | 6 ++ app/platform/usart_ll.h | 6 ++ app/stats.h | 68 ---------------- lib/console_handler.c | 2 +- lib/console_handler.h | 2 +- lib/crc_handler.c | 15 ++-- lib/crc_handler.h | 32 ++++---- lib/dma_helper.h | 2 +- lib/memcpy_dma.c | 1 - lib/memcpy_dma.h | 4 +- lib/usart_handler.c | 110 ++++++++++++++++--------- lib/usart_handler.h | 173 +++++++++++++++++++++++++++------------- 18 files changed, 244 insertions(+), 204 deletions(-) create mode 100644 app/platform/crc_ll.h create mode 100644 app/platform/dma_ll.h create mode 100644 app/platform/usart_ll.h delete mode 100644 app/stats.h diff --git a/app/application.c b/app/application.c index 3f0629b..2e0b007 100644 --- a/app/application.c +++ b/app/application.c @@ -12,12 +12,12 @@ #define PACKAGE_DELAY_MS 0 #define STATS_DELAY_MS 1000 -// UART DMA RX TX +// USART DMA RX TX // 1 2 2 7 // 2 1 5 6 // 3 1 1 3 // 6 2 1 6 -// console UART +// console USART // 4 1 2 4 void MainLoop() @@ -53,7 +53,7 @@ void MainLoop() 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, idx + UARTCOUNT, idx); + &g_crcStatus, idx + USARTCOUNT, idx, NULL, NULL); memcpy(GetTxBuffer(&g_uartStatuses[idx]), text2Send, sizeof(text2Send) -1); } @@ -92,7 +92,7 @@ void MainLoop() PrintStats((char*)g_statsBuf, statId, &g_uartStatuses[statId].stats, UART4, &g_ConsoleTxDmaInfo); lastStatsTick += STATS_DELAY_MS; ++statId; - if(statId >= UARTCOUNT) + if(statId >= USARTCOUNT) statId = 0; } uint32_t ein = LL_GPIO_ReadInputPort(KEY1_GPIO_Port); diff --git a/app/application.h b/app/application.h index 4c12d60..fd15a99 100644 --- a/app/application.h +++ b/app/application.h @@ -10,7 +10,6 @@ #include #include "main.h" -#include void MainLoop(); diff --git a/app/config.h b/app/config.h index f518e94..92c392f 100644 --- a/app/config.h +++ b/app/config.h @@ -8,8 +8,8 @@ #ifndef CONFIG_H_ #define CONFIG_H_ -#define UARTCOUNT 4 -#define CRCTASKCOUNT (UARTCOUNT * 2) +#define USARTCOUNT 4 +#define CRCTASKCOUNT (USARTCOUNT * 2) #define USART1_OFFSET 0 #define USART2_OFFSET 1 #define USART3_OFFSET 2 diff --git a/app/globals.c b/app/globals.c index b167ff3..540cb61 100644 --- a/app/globals.c +++ b/app/globals.c @@ -7,9 +7,9 @@ #include "globals.h" -UARTSTATUS g_uartStatuses[UARTCOUNT]; +USARTSTATUS g_uartStatuses[USARTCOUNT]; -struct crcstatus_t g_crcStatus; +CRCSTATUS g_crcStatus; DMAINFO g_ConsoleTxDmaInfo; uint8_t g_statsBuf[128]; diff --git a/app/globals.h b/app/globals.h index 955ba0f..526fd13 100644 --- a/app/globals.h +++ b/app/globals.h @@ -14,9 +14,9 @@ #include "dma_helper.h" #include "crc_handler.h" -extern UARTSTATUS g_uartStatuses[UARTCOUNT]; +extern USARTSTATUS g_uartStatuses[USARTCOUNT]; -extern struct crcstatus_t g_crcStatus; +extern CRCSTATUS g_crcStatus; extern DMAINFO g_ConsoleTxDmaInfo; extern uint8_t g_statsBuf[128]; diff --git a/app/platform/crc_ll.h b/app/platform/crc_ll.h new file mode 100644 index 0000000..f10b7bc --- /dev/null +++ b/app/platform/crc_ll.h @@ -0,0 +1,6 @@ +#ifndef __PLATFORM_CRC_LL_H_INCLUDED +#define __PLATFORM_CRC_LL_H_INCLUDED + +#include "crc.h" + +#endif // __PLATFORM_CRC_LL_H_INCLUDED diff --git a/app/platform/dma_ll.h b/app/platform/dma_ll.h new file mode 100644 index 0000000..a39ab1c --- /dev/null +++ b/app/platform/dma_ll.h @@ -0,0 +1,6 @@ +#ifndef __PLATFORM_DMA_LL_H_INCLUDED +#define __PLATFORM_DMA_LL_H_INCLUDED + +#include "dma.h" + +#endif // __PLATFORM_DMA_LL_H_INCLUDED diff --git a/app/platform/usart_ll.h b/app/platform/usart_ll.h new file mode 100644 index 0000000..52354de --- /dev/null +++ b/app/platform/usart_ll.h @@ -0,0 +1,6 @@ +#ifndef __PLATFORM_USART_LL_H_INCLUDED +#define __PLATFORM_USART_LL_H_INCLUDED + +#include "usart.h" + +#endif // __PLATFORM_USART_LL_H_INCLUDED diff --git a/app/stats.h b/app/stats.h deleted file mode 100644 index 29f1b5c..0000000 --- a/app/stats.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * stats.h - * - * Created on: Sep 16, 2019 - * Author: abody - */ - -#ifndef STATS_H_ -#define STATS_H_ -#include "diag.h" - -#ifndef DIAG_ERROR_EVENT -# define DIAG_ERROR_EVENT() -#endif - -typedef struct { - uint32_t overrun; - uint32_t hdrError; - uint32_t lastErrHdr; - uint32_t payloadErrror; - uint32_t pep1, pep2; - uint32_t dmaError; - uint32_t rcvd; - uint32_t premature_hdr; - uint32_t premature_payload; - uint32_t sent; - uint32_t skiped; -} STATS; - -#ifndef STATS_DISABLED -static inline void StatsIncOverrun(STATS *s) { - ++s->overrun; -} -static inline void StatsIncHdrError(STATS *s, uint32_t hdr) { - DIAG_ERROR_EVENT(); - ++s->hdrError; -} -static inline void StatsIncPayloadError(STATS *s, uint32_t pep1, uint32_t pep2) { - DIAG_ERROR_EVENT(); - ++s->payloadErrror; - s->pep1 = pep1; - s->pep2 = pep2; -} -static inline void StatsIncDmaError(STATS *s) { - DIAG_ERROR_EVENT(); - ++s->dmaError; -} -static inline void StatsIncRcvd(STATS *s) { - ++s->rcvd; -} -static inline void StatsIncPremature_hdr(STATS *s) { - ++s->premature_hdr; -} -static inline void StatsIncPremature_payload(STATS *s) { - ++s->premature_payload; -} -static inline void StatsIncSent(STATS *s) { - ++s->sent; -} -static inline void StatsAddSkiped(STATS *s, uint8_t cnt) { - s->skiped += s->rcvd > 2 ? cnt : 0; -} - -#else // STATS_DISABLED -#define StatsIncSent(x) -#endif // STATS_DISABLED - -#endif /* STATS_H_ */ diff --git a/lib/console_handler.c b/lib/console_handler.c index 8dc2e97..a3fa56a 100644 --- a/lib/console_handler.c +++ b/lib/console_handler.c @@ -40,7 +40,7 @@ void HandleConsoleUsartIrq(USART_TypeDef *usart) b += strcpy_ex(b,s); \ b += uitodec(b,u); -void PrintStats(char *buffer, uint8_t id, STATS *stats, USART_TypeDef *usart, DMAINFO *dmaInfo) +void PrintStats(char *buffer, uint8_t id, struct usart_stats *stats, USART_TypeDef *usart, DMAINFO *dmaInfo) { char ids[] = " : "; char *bs = buffer; diff --git a/lib/console_handler.h b/lib/console_handler.h index ac29329..3e17705 100644 --- a/lib/console_handler.h +++ b/lib/console_handler.h @@ -14,6 +14,6 @@ void HandleConsoleUsartTxDmaIrq(DMAINFO *info, USART_TypeDef *usart); void HandleConsoleUsartIrq(USART_TypeDef *usart); -void PrintStats(char *buffer, uint8_t id, STATS *stats, USART_TypeDef *usart, DMAINFO *dmaInfo); +void PrintStats(char *buffer, uint8_t id, struct usart_stats *stats, USART_TypeDef *usart, DMAINFO *dmaInfo); #endif /* INTERRUPT_HANDLERS_H_ */ diff --git a/lib/crc_handler.c b/lib/crc_handler.c index e27dc53..0764702 100644 --- a/lib/crc_handler.c +++ b/lib/crc_handler.c @@ -4,9 +4,8 @@ * Created on: Aug 29, 2019 * Author: abody */ -#include #include -#include "crc.h" +#include #include "dma_helper.h" #include "diag.h" #include "crc_handler.h" @@ -28,7 +27,7 @@ #endif -void InitCrcStatus(struct crcstatus_t *st, DMA_TypeDef *dma, uint32_t stream) +void InitCrcStatus(CRCSTATUS *st, DMA_TypeDef *dma, uint32_t stream) { InitDmaInfo(&st->dmaInfo, dma, stream); LL_DMA_EnableIT_TC(dma, stream); @@ -38,7 +37,7 @@ void InitCrcStatus(struct crcstatus_t *st, DMA_TypeDef *dma, uint32_t stream) memset((void*)st->crcTasks, 0, sizeof(st->crcTasks)); } -uint8_t EnqueueCrcTask(struct crcstatus_t *status, uint8_t slot, uint8_t *address, uint16_t len, +uint8_t EnqueueCrcTask(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam) { uint32_t prim = __get_PRIMASK(); @@ -65,13 +64,13 @@ uint8_t EnqueueCrcTask(struct crcstatus_t *status, uint8_t slot, uint8_t *addres return need_start; } -void WaitCrcResults(struct crcstatus_t *status, uint8_t slot) +void WaitCrcResults(CRCSTATUS *status, uint8_t slot) { while(IsSlotQueued(status, slot)); while(GetActiveSlot(status) == slot); } -uint32_t ComputeCrc(struct crcstatus_t *status, uint8_t slot, uint8_t *address, uint16_t len) +uint32_t ComputeCrc(CRCSTATUS *status, uint8_t slot, uint8_t *address, uint16_t len) { uint32_t result; EnqueueCrcTask(status, slot, address, len, NULL, &result); @@ -79,7 +78,7 @@ uint32_t ComputeCrc(struct crcstatus_t *status, uint8_t slot, uint8_t *address, return result; } -void StartNextCrcTask(struct crcstatus_t *status) +void StartNextCrcTask(CRCSTATUS *status) { uint16_t slot; for(slot = 0; slot < CRCTASKCOUNT; ++slot) @@ -97,7 +96,7 @@ void StartNextCrcTask(struct crcstatus_t *status) status->activeSlot = 0xff; } -void HandleCrcDmaIrq(struct crcstatus_t *status) +void HandleCrcDmaIrq(CRCSTATUS *status) { DIAG_INTERRUPT_IN(); if(*status->dmaInfo.isReg & status->dmaInfo.tcMask) { // DMA transfer complete diff --git a/lib/crc_handler.h b/lib/crc_handler.h index b0cf297..7f88632 100644 --- a/lib/crc_handler.h +++ b/lib/crc_handler.h @@ -9,14 +9,18 @@ #define CRC_HANDLER_H_ #include -#include + +#ifdef HAVE_CONFIG #include "config.h" +#endif // HAVE_CONFIG + +#include #ifndef CRCTASKCOUNT -#define CRCTASKCOUNT 8 +#define CRCTASKCOUNT 2 #endif -struct crcstatus_t { +typedef struct { DMAINFO dmaInfo; volatile uint8_t activeSlot; struct crctask_t { @@ -25,27 +29,25 @@ struct crcstatus_t { void (*callback)(void*, uint32_t, uint8_t); void *callbackParam; } volatile crcTasks[CRCTASKCOUNT]; -}; +} CRCSTATUS; -//#define CRCTASKCOUNT (sizeof(((struct crcstatus_t*)0)->crcTasks)/sizeof(struct crctask_t)) - -void InitCrcStatus(struct crcstatus_t *status, DMA_TypeDef *dma, uint32_t stream); -static inline uint8_t GetActiveSlot(struct crcstatus_t *status) { +void InitCrcStatus(CRCSTATUS *status, DMA_TypeDef *dma, uint32_t stream); +static inline uint8_t GetActiveSlot(CRCSTATUS *status) { return status->activeSlot; } -static inline uint8_t IsSlotQueued(struct crcstatus_t *status, uint8_t slot) { +static inline uint8_t IsSlotQueued(CRCSTATUS *status, uint8_t slot) { return status->crcTasks[slot].address != NULL; } -static inline uint8_t IsSlotActive(struct crcstatus_t *status, uint8_t slot) { +static inline uint8_t IsSlotActive(CRCSTATUS *status, uint8_t slot) { return status->crcTasks[slot].callback != NULL || status->crcTasks[slot].callbackParam != NULL; } -uint8_t EnqueueCrcTask(struct crcstatus_t *crcStatus, uint8_t slot, uint8_t *address, uint16_t len, +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(struct crcstatus_t *status, uint8_t slot); -uint32_t ComputeCrc(struct crcstatus_t *status, uint8_t slot, uint8_t *address, uint16_t len); -void ComputeCrcAsync(struct crcstatus_t *status, uint8_t slot, +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, uint8_t *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam); -void HandleCrcDmaIrq(struct crcstatus_t *status); +void HandleCrcDmaIrq(CRCSTATUS *status); #endif /* CRC_HANDLER_H_ */ diff --git a/lib/dma_helper.h b/lib/dma_helper.h index f2c5f75..4cb609a 100644 --- a/lib/dma_helper.h +++ b/lib/dma_helper.h @@ -8,7 +8,7 @@ #ifndef DMA_HELPER_H_ #define DMA_HELPER_H_ #include -#include "dma.h" +#include typedef struct { DMA_TypeDef *dma; diff --git a/lib/memcpy_dma.c b/lib/memcpy_dma.c index 8a28880..0c3a654 100644 --- a/lib/memcpy_dma.c +++ b/lib/memcpy_dma.c @@ -31,7 +31,6 @@ void * MemcpyDma(void *dst, void const *src, size_t length) LL_DMA_SetM2MDstAddress(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (uint32_t)dst); LL_DMA_SetDataLength(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (length+3)/4 ); g_memcpyDmaBusy = 1; - //DIAG_CRC_CALC_START(); LL_DMA_EnableStream(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream); while(g_memcpyDmaBusy); return dst; diff --git a/lib/memcpy_dma.h b/lib/memcpy_dma.h index 9eab257..60e4263 100644 --- a/lib/memcpy_dma.h +++ b/lib/memcpy_dma.h @@ -9,9 +9,7 @@ #define MEMCPY_DMA_H_ #include -#include "dma.h" -//#include "dma_helper.h" -//extern DMAINFO g_memcpyDmaInfo; +#include void InitMemcpyDma(DMA_TypeDef *dma, uint32_t stream); void * MemcpyDma(void *dst, void const *src, size_t length); diff --git a/lib/usart_handler.c b/lib/usart_handler.c index e71feb1..1a5232a 100644 --- a/lib/usart_handler.c +++ b/lib/usart_handler.c @@ -1,12 +1,12 @@ /* - * uart_handler.c + * usart_handler.c * * Created on: Sep 16, 2019 * Author: abody */ #include -#include "globals.h" +#include #include "diag.h" #include "usart_handler.h" #include "dma_helper.h" @@ -23,13 +23,20 @@ # define DIAG_INTERRUPT_OUT() #endif +#define STARTMARKER 0x95 + +static inline uint32_t RoundUpTo4(uint32_t inp) +{ + return (inp + 3) & 0xfffc; +} void InitUartStatus( - UARTSTATUS *st, USART_TypeDef *uart, DMA_TypeDef *dma, + USARTSTATUS *st, USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, - struct crcstatus_t *crcStatus, uint8_t rxCrcSlot, uint8_t txCrcSlot) + CRCSTATUS *crcStatus, uint8_t rxCrcSlot, uint8_t txCrcSlot, + PACKETRECEIVEDCALLBACK packetReceivedCallback, void * packetReceivedCallbackParam) { - st->uart = uart; + st->usart = usart; InitDmaInfo(&st->rxDmaInfo, dma, stream_rx); InitDmaInfo(&st->txDmaInfo, dma, stream_tx); st->txBuffer.busy = 0; @@ -41,6 +48,11 @@ void InitUartStatus( st->rxBuffers[1].error = 0; st->rxBuffers[0].requestedLength = 0; st->rxBuffers[1].requestedLength = 0; + st->txBuffer.usartStatus = st; + st->rxBuffers[0].usartStatus = st; + st->rxBuffers[1].usartStatus = st; + st->packetReceivedCallback = packetReceivedCallback; + st->packetReceivedCallbacParam = packetReceivedCallbackParam; st->rxSerial = -1; st->txSerial = 0; st->activeRxBuf = 0; @@ -53,10 +65,17 @@ void InitUartStatus( LL_DMA_EnableIT_TE(dma, stream_rx); LL_DMA_EnableIT_TC(dma, stream_tx); LL_DMA_EnableIT_TE(dma, stream_tx); - LL_USART_EnableIT_IDLE(uart); + LL_USART_EnableIT_IDLE(usart); } -static inline void BuildHeader(UARTBUFFER *buffer, uint8_t serial, uint8_t length) + +uint8_t* GetTxBuffer(USARTSTATUS *status) +{ + return status->txBuffer.packet.payload; +} + + +static inline void BuildHeader(struct usart_buffer *buffer, uint8_t serial, uint8_t length) { uint8_t hash = STARTMARKER; buffer->packet.header.startByte = STARTMARKER; @@ -67,51 +86,61 @@ static inline void BuildHeader(UARTBUFFER *buffer, uint8_t serial, uint8_t lengt buffer->packet.header.hash = hash; } -static inline uint8_t CheckHeader(UARTPACKET *packet) { +static inline uint8_t CheckHeader(USARTPACKET *packet) { return packet->header.startByte == STARTMARKER && (packet->header.startByte ^ packet->header.serial ^ packet->header.payloadLength) == packet->header.hash; } -uint8_t PostPacket(UARTSTATUS *status, uint8_t const *payload, uint16_t length, struct crcstatus_t *crcStatus) +uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, CRCSTATUS *crcStatus) { if(length > 256) return 1; BuildHeader(&status->txBuffer, status->txSerial++, length); - uint16_t payloadLength = (length+3) & 0xfffc; // round up to 4 - if(payload) - MemcpyDma(status->txBuffer.packet.payload, payload, length); - status->txBuffer.requestedLength = sizeof(UARTPACKETHEADER) + payloadLength + sizeof(uint32_t); // +4 for the hash + uint16_t payloadLength = RoundUpTo4(length); + if(payload) { +#ifdef USART_USE_MEMCPY_DMA + if((uint32_t)payload & 3) + memcpy(status->txBuffer.packet.payload, payload, length); + else + MemcpyDma(status->txBuffer.packet.payload, payload, length); +#else + memcpy(status->txBuffer.packet.payload, payload, length); +#endif + } + 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, NULL, (uint32_t*)(status->txBuffer.packet.payload + payloadLength)); while(IsSlotQueued(crcStatus, status->txCrcSlot)); - SetupTransmit(status->uart, status->txDmaInfo.dma, status->txDmaInfo.stream, &status->txBuffer.packet, status->txBuffer.requestedLength); + SetupTransmit(status->usart, status->txDmaInfo.dma, status->txDmaInfo.stream, &status->txBuffer.packet, status->txBuffer.requestedLength); StatsIncSent(&status->stats); return 0; } -void SetupReceive(UARTSTATUS *status) + +void SetupReceive(USARTSTATUS *status) { uint8_t packetIndex = status->activeRxBuf; - LL_DMA_ConfigAddresses(status->rxDmaInfo.dma, status->rxDmaInfo.stream, LL_USART_DMA_GetRegAddr(status->uart), (uint32_t)&status->rxBuffers[packetIndex], - LL_DMA_GetDataTransferDirection(status->rxDmaInfo.dma, status->rxDmaInfo.stream)); + LL_DMA_ConfigAddresses(status->rxDmaInfo.dma, status->rxDmaInfo.stream, LL_USART_DMA_GetRegAddr(status->usart), (uint32_t)&status->rxBuffers[packetIndex], + LL_DMA_DIRECTION_PERIPH_TO_MEMORY); status->rxBuffers[packetIndex].requestedLength = sizeof(status->rxBuffers[packetIndex].packet); LL_DMA_SetDataLength(status->rxDmaInfo.dma, status->rxDmaInfo.stream, status->rxBuffers[packetIndex].requestedLength); // payload already have extra room for hash - LL_USART_EnableDMAReq_RX(status->uart); - LL_USART_ClearFlag_ORE(status->uart); + LL_USART_EnableDMAReq_RX(status->usart); + LL_USART_ClearFlag_ORE(status->usart); LL_DMA_EnableStream(status->rxDmaInfo.dma, status->rxDmaInfo.stream); } -void ConsumePacket(UARTSTATUS *status, uint8_t packetIndex, struct crcstatus_t *crcStatus) + +void ConsumePacket(USARTSTATUS *status, uint8_t packetIndex, CRCSTATUS *crcStatus) { - UARTBUFFER *buffer = &status->rxBuffers[packetIndex]; + struct usart_buffer *buffer = &status->rxBuffers[packetIndex]; if(buffer->busy) { if(buffer->error) - StatsIncPayloadError(&status->stats, buffer->errorInfo, *(uint32_t*) (buffer->packet.payload + ((buffer->packet.header.payloadLength + 1 + 3) & 0xfffc))); + StatsIncPayloadError(&status->stats, buffer->errorInfo, *(uint32_t*) (buffer->packet.payload + RoundUpTo4(buffer->packet.header.payloadLength + 1))); else { uint8_t diff = buffer->packet.header.serial - status->rxSerial; if(diff > 1) @@ -123,28 +152,31 @@ void ConsumePacket(UARTSTATUS *status, uint8_t packetIndex, struct crcstatus_t * buffer->busy = buffer->error = 0; } -void SetupTransmit(USART_TypeDef *uart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length) + +void SetupTransmit(USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length) { - LL_DMA_ConfigAddresses(dma, stream, (uint32_t)buffer, LL_USART_DMA_GetRegAddr(uart), LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + LL_DMA_ConfigAddresses(dma, stream, (uint32_t)buffer, LL_USART_DMA_GetRegAddr(usart), LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetDataLength(dma, stream, length); - LL_USART_EnableDMAReq_TX(uart); + LL_USART_EnableDMAReq_TX(usart); LL_DMA_EnableStream(dma, stream); } void RxCrcComputedCallback(void *callbackParm, uint32_t calculatedCrc, uint8_t success) { - UARTBUFFER *ub = (UARTBUFFER*) callbackParm; + struct usart_buffer *ub = (struct usart_buffer*) callbackParm; if(!success) ub->error = 1; - else if(*(uint32_t*) (ub->packet.payload + ((ub->packet.header.payloadLength + 1 + 3) & 0xfffc)) == calculatedCrc) + else if(*(uint32_t*) (ub->packet.payload + RoundUpTo4(ub->packet.header.payloadLength + 1))) ub->busy = 1; else { ub->error = ub->busy = 1; ub->errorInfo = calculatedCrc; } + if(ub->usartStatus->packetReceivedCallback) + ub->usartStatus->packetReceivedCallback(ub->usartStatus->packetReceivedCallbacParam, ub); } -void HandleUsartRxDmaIrq(UARTSTATUS *status) +void HandleUsartRxDmaIrq(USARTSTATUS *status) { DIAG_INTERRUPT_IN(); StatsIncRcvd(&status->stats); @@ -173,12 +205,12 @@ void HandleUsartRxDmaIrq(UARTSTATUS *status) DIAG_INTERRUPT_OUT(); } -void HandleUsartTxDmaIrq(UARTSTATUS *status) +void HandleUsartTxDmaIrq(USARTSTATUS *status) { DIAG_INTERRUPT_IN(); if(*status->txDmaInfo.isReg & status->txDmaInfo.tcMask) { // DMA transfer complete *status->txDmaInfo.ifcReg = status->txDmaInfo.tcMask; - LL_USART_EnableIT_TC(status->uart); + LL_USART_EnableIT_TC(status->usart); LL_DMA_DisableStream(status->txDmaInfo.dma, status->txDmaInfo.stream); } else if(*status->txDmaInfo.isReg & status->txDmaInfo.teMask) { @@ -195,15 +227,15 @@ void HandleUsartTxDmaIrq(UARTSTATUS *status) DIAG_INTERRUPT_OUT(); } -void HandleUsartIrq(UARTSTATUS *status) +void HandleUsartIrq(USARTSTATUS *status) { DIAG_INTERRUPT_IN(); - if(LL_USART_IsActiveFlag_IDLE(status->uart) && LL_USART_IsEnabledIT_IDLE(status->uart)) { // receiver idle - LL_USART_ClearFlag_IDLE(status->uart); + if(LL_USART_IsActiveFlag_IDLE(status->usart) && LL_USART_IsEnabledIT_IDLE(status->usart)) { // receiver idle + LL_USART_ClearFlag_IDLE(status->usart); uint16_t rcvdLen = status->rxBuffers[status->activeRxBuf].requestedLength - LL_DMA_GetDataLength(status->rxDmaInfo.dma, status->rxDmaInfo.stream); - if(rcvdLen >= sizeof(UARTPACKETHEADER)) { + if(rcvdLen >= sizeof(USARTPACKETHEADER)) { if(CheckHeader(&status->rxBuffers[status->activeRxBuf].packet)) { - if(rcvdLen >= sizeof(UARTPACKETHEADER) + ((status->rxBuffers[status->activeRxBuf].packet.header.payloadLength + 1 + 3) &0xfffc) + sizeof(uint32_t)) + if(rcvdLen >= sizeof(USARTPACKETHEADER) + RoundUpTo4(status->rxBuffers[status->activeRxBuf].packet.header.payloadLength + 1) + sizeof(uint32_t)) LL_DMA_DisableStream(status->rxDmaInfo.dma, status->rxDmaInfo.stream); else StatsIncPremature_payload(&status->stats); @@ -214,10 +246,10 @@ void HandleUsartIrq(UARTSTATUS *status) } else StatsIncPremature_hdr(&status->stats); } - else if(LL_USART_IsActiveFlag_TC(status->uart) && LL_USART_IsEnabledIT_TC(status->uart)) { // transmission complete - LL_USART_DisableIT_TC(status->uart); - LL_USART_DisableDirectionTx(status->uart); // enforcing an idle frame - LL_USART_EnableDirectionTx(status->uart); + else if(LL_USART_IsActiveFlag_TC(status->usart) && LL_USART_IsEnabledIT_TC(status->usart)) { // transmission complete + LL_USART_DisableIT_TC(status->usart); + LL_USART_DisableDirectionTx(status->usart); // enforcing an idle frame + LL_USART_EnableDirectionTx(status->usart); status->txBuffer.busy = 0; } DIAG_INTERRUPT_OUT(); diff --git a/lib/usart_handler.h b/lib/usart_handler.h index e62e2c0..80b777d 100644 --- a/lib/usart_handler.h +++ b/lib/usart_handler.h @@ -1,81 +1,142 @@ /* - * uart_handler.h + * usart_handler.h * * Created on: Sep 16, 2019 * Author: abody */ -#ifndef UART_HANDLER_H_ -#define UART_HANDLER_H_ +#ifndef USART_HANDLER_H_ +#define USART_HANDLER_H_ #include -#include -#include #include "dma_helper.h" #include "crc_handler.h" -/* - * TH UART RXDMA TXDMA - * 0 1 D2S5 D2S7 - * 1 3 D1S1 D1S3 - * 2 2 D1S5 D1S6 - * 3 6 D2S2 D2S6 +struct _usart_status; +typedef struct _usart_status USARTSTATUS; +struct usart_buffer; + +typedef void (*PACKETRECEIVEDCALLBACK)(void *userParam, struct usart_buffer *buffer); + +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, + PACKETRECEIVEDCALLBACK packetReceivedCallback, void * packetReceivedCallbackParam); + +uint8_t* GetTxBuffer(USARTSTATUS *status); + +uint8_t PostPacket(USARTSTATUS *status, uint8_t const *payload, uint16_t length, CRCSTATUS *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 HandleUsartRxDmaIrq(USARTSTATUS *status); +void HandleUsartTxDmaIrq(USARTSTATUS *status); +void HandleUsartIrq(USARTSTATUS *status); + +/****************************************************************************************** + * + * + * */ + +struct usart_stats { + uint32_t overrun; + uint32_t hdrError; + uint32_t lastErrHdr; + uint32_t payloadErrror; + uint32_t pep1, pep2; + uint32_t dmaError; + uint32_t rcvd; + uint32_t premature_hdr; + uint32_t premature_payload; + uint32_t sent; + uint32_t skiped; +}; typedef struct { - uint8_t startByte; + uint8_t startByte; uint8_t serial; uint8_t payloadLength; uint8_t hash; -} UARTPACKETHEADER; - -typedef struct -{ - UARTPACKETHEADER header; - //!!! should start on word offset !!! - uint8_t payload[256+sizeof(uint32_t)]; // extra room for crc32 -} __attribute__((aligned)) UARTPACKET; - -typedef struct _UARTBUFFER { - UARTPACKET packet; - //transfer area ends here - volatile uint8_t busy; - volatile uint8_t error; - uint16_t requestedLength; - uint32_t errorInfo; -} UARTBUFFER; +} USARTPACKETHEADER; typedef struct { - USART_TypeDef *uart; - DMAINFO rxDmaInfo; - DMAINFO txDmaInfo; - struct crcstatus_t *crcStatus; - uint8_t rxSerial; - uint8_t txSerial; - STATS stats; - uint8_t activeRxBuf; - uint8_t rxCrcSlot; - uint8_t txCrcSlot; - UARTBUFFER txBuffer; - UARTBUFFER rxBuffers[2]; -} UARTSTATUS; + USARTPACKETHEADER header; + //!!! should start on word offset !!! + uint8_t payload[256+sizeof(uint32_t)]; // extra room for crc32 +} __attribute__((aligned)) USARTPACKET; -#define STARTMARKER 0x95 +struct usart_buffer { + USARTPACKET packet; + //transfer area ends here + volatile uint8_t busy; + volatile uint8_t error; + uint16_t requestedLength; + uint32_t errorInfo; + USARTSTATUS *usartStatus; +}; -void InitUartStatus( - UARTSTATUS *st, USART_TypeDef *uart, DMA_TypeDef *dma, - uint32_t stream_rx, uint32_t stream_tx, - struct crcstatus_t *crcStatus, uint8_t rxCrcSlot, uint8_t txCrcSlot); -static inline uint8_t* GetTxBuffer(UARTSTATUS *status) { - return status->txBuffer.packet.payload; +struct _usart_status { + USART_TypeDef *usart; + DMAINFO rxDmaInfo; + DMAINFO txDmaInfo; + CRCSTATUS *crcStatus; + 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; + struct usart_buffer rxBuffers[2]; +}; + +#ifndef USART_STATS_DISABLED +static inline void StatsIncOverrun(struct usart_stats *s) { + ++s->overrun; +} +static inline void StatsIncHdrError(struct usart_stats *s, uint32_t hdr) { + ++s->hdrError; + s->lastErrHdr = hdr; +} +static inline void StatsIncPayloadError(struct usart_stats *s, uint32_t pep1, uint32_t pep2) { + ++s->payloadErrror; + s->pep1 = pep1; + s->pep2 = pep2; +} +static inline void StatsIncDmaError(struct usart_stats *s) { + ++s->dmaError; +} +static inline void StatsIncRcvd(struct usart_stats *s) { + ++s->rcvd; +} +static inline void StatsIncPremature_hdr(struct usart_stats *s) { + ++s->premature_hdr; +} +static inline void StatsIncPremature_payload(struct usart_stats *s) { + ++s->premature_payload; +} +static inline void StatsIncSent(struct usart_stats *s) { + ++s->sent; +} +static inline void StatsAddSkiped(struct usart_stats *s, uint8_t cnt) { + s->skiped += s->rcvd > 2 ? cnt : 0; } -uint8_t PostPacket(UARTSTATUS *status, uint8_t const *payload, uint16_t length, struct crcstatus_t *crcStatus); -void SetupReceive(UARTSTATUS *status); -void SetupTransmit(USART_TypeDef *uart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length); -void ConsumePacket(UARTSTATUS *status, uint8_t packetIndex, struct crcstatus_t *crcStatus); -void HandleUsartRxDmaIrq(UARTSTATUS *status); -void HandleUsartTxDmaIrq(UARTSTATUS *status); -void HandleUsartIrq(UARTSTATUS *status); +#else // USART_STATS_DISABLED +#define StatsIncOverrun(x) +#define StatsIncHdrError(x,y) +#define StatsIncPayloadError(x,y,z) +#define StatsIncDmaError(x) +#define StatsIncRcvd(x) +#define StatsIncPremature_hdr(x) +#define StatsIncPremature_payload(x) +#define StatsIncSent(x) +#define StatsAddSkiped(x) +#endif // USART_STATS_DISABLED #endif /* UART_HANDLER_H_ */