From 174f5e8d764b07403a5ea14ba988ef0209624b5b Mon Sep 17 00:00:00 2001 From: Stefano Calabretti <45517710+cala-br@users.noreply.github.com> Date: Tue, 25 Jan 2022 18:12:33 +0100 Subject: [PATCH] Multiple frames (#8) * Add fields to mmr header * Reorder priority constants * Add message priority * Add header to message * Fix compile error * Set correct bits in header * Refactor * Create queue --- Inc/mmr_can.h | 2 +- Inc/mmr_can_header.h | 16 +++++- Inc/mmr_can_queue.h | 14 +++++ Src/mmr_can_header.c | 9 +++ Src/mmr_can_receive.c | 18 +++--- Src/mmr_can_send.c | 127 +++++++++++++++++++++++------------------- 6 files changed, 117 insertions(+), 69 deletions(-) create mode 100644 Inc/mmr_can_queue.h diff --git a/Inc/mmr_can.h b/Inc/mmr_can.h index 5f24104..6304c4c 100644 --- a/Inc/mmr_can.h +++ b/Inc/mmr_can.h @@ -78,7 +78,7 @@ typedef struct { * Represents a CAN message */ typedef struct { - CanId senderId; + MmrCanHeader header; void *store; } MmrCanMessage; diff --git a/Inc/mmr_can_header.h b/Inc/mmr_can_header.h index eb42455..c148cce 100644 --- a/Inc/mmr_can_header.h +++ b/Inc/mmr_can_header.h @@ -24,18 +24,30 @@ typedef enum { } MmrCanMessageType; + +typedef enum { + MMR_CAN_MESSAGE_PRIORITY_LOW = B_(0010), + MMR_CAN_MESSAGE_PRIORITY_NORMAL = B_(0001), + MMR_CAN_MESSAGE_PRIORITY_HIGH = B_(0000), +} MmrCanMessagePriority; + + /** * @brief * This struct encodes the values stored inside the * extended id field of a CAN packet. */ typedef struct { - uint32_t priority : 5; - uint32_t senderId : 23; + MmrCanMessagePriority priority : 3; + uint32_t dictionaryEntry : 10; + uint32_t senderId : 12; MmrCanMessageType messageType : 4; } MmrCanHeader; +uint32_t *MMR_CAN_HeaderToBits(MmrCanHeader *header); +MmrCanHeader *MMR_CAN_HeaderFromBits(uint32_t *bits); + bool MMR_CAN_IsMultiFrame(MmrCanHeader *header); bool MMR_CAN_IsMultiFrameEnd(MmrCanHeader *header); diff --git a/Inc/mmr_can_queue.h b/Inc/mmr_can_queue.h new file mode 100644 index 0000000..11f3b0a --- /dev/null +++ b/Inc/mmr_can_queue.h @@ -0,0 +1,14 @@ +#ifndef INC_MMR_CAN_QUEUE_H_ +#define INC_MMR_CAN_QUEUE_H_ + +#include +#include "mmr_can.h" + +#define MMR_CAN_QUEUE_SIZE 10 + +typedef struct { + MmrCanMessage messages[MMR_CAN_QUEUE_SIZE]; + size_t count; +} MmrCanQueue; + +#endif /* INC_MMR_CAN_QUEUE_H_ */ diff --git a/Src/mmr_can_header.c b/Src/mmr_can_header.c index 1b670b5..8ceb707 100644 --- a/Src/mmr_can_header.c +++ b/Src/mmr_can_header.c @@ -1,6 +1,15 @@ #include "mmr_can_header.h" +#include "mmr_can_util.h" #include "mmr_can_optimize.h" +uint32_t *MMR_CAN_HeaderToBits(MmrCanHeader *header) { + return (uint32_t*)header; +} + +MmrCanHeader *MMR_CAN_HeaderFromBits(uint32_t *bits) { + return (MmrCanHeader*)bits; +} + bool MMR_CAN_IsMultiFrame(MmrCanHeader *header) { return header->messageType == MMR_CAN_MESSAGE_TYPE_MULTI_FRAME; diff --git a/Src/mmr_can_receive.c b/Src/mmr_can_receive.c index 51cd84e..3627f2f 100644 --- a/Src/mmr_can_receive.c +++ b/Src/mmr_can_receive.c @@ -1,14 +1,11 @@ #include #include "mmr_can.h" -static HalStatus receiveOne(ReceptionParams *rp); -static HalStatus receiveAll(ReceptionParams *rp); -static bool headerIsMultiFrame(MmrCanHeader *header, CanId targetId); - typedef struct { CanHandle *handle; uint8_t *result; + struct { CanRxHeader rx; MmrCanHeader mmr; @@ -18,6 +15,11 @@ typedef struct { } ReceptionParams; +static HalStatus receiveOne(ReceptionParams *rp); +static HalStatus receiveAll(ReceptionParams *rp); +static bool headerIsMultiFrame(MmrCanHeader *header, CanId targetId); + + /** * @brief * Reads a CAN message and stores it inside the @@ -29,7 +31,7 @@ typedef struct { HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) { ReceptionParams rp = { .handle = hcan, - .result = interpretAs(uint8_t*, result->store), + .result = (uint8_t*)result->store, .fifo = MMR_CAN_RX_FIFO, }; @@ -38,7 +40,7 @@ HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) { return status; } - result->senderId = rp.headers.mmr.senderId; + result->header = rp.headers.mmr; if (MMR_CAN_IsMultiFrame(&rp.headers.mmr)) { status |= receiveAll(&rp); } @@ -63,9 +65,9 @@ static HalStatus receiveAll(ReceptionParams *rp) { static HalStatus receiveOne(ReceptionParams *rp) { HalStatus status = - HAL_CAN_GetRxMessage(rp->hcan, rp->fifo, &(rp->headers.rx), rp->result); + HAL_CAN_GetRxMessage(rp->handle, rp->fifo, &(rp->headers.rx), rp->result); - rp->headers.mmr = convertTo(MmrCanHeader, header->ExtId); + rp->headers.mmr = convertTo(MmrCanHeader, rp->headers.rx.ExtId); return status; } diff --git a/Src/mmr_can_send.c b/Src/mmr_can_send.c index 341d38d..1c06ba8 100644 --- a/Src/mmr_can_send.c +++ b/Src/mmr_can_send.c @@ -3,57 +3,63 @@ #include "mmr_can_util.h" -static HalStatus sendNormal(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet); -static HalStatus sendMulti(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet); -static HalStatus sendSingleMultiFrame(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet, uint8_t *offset); -static uint8_t computeFramesToSend(MmrCanPacket *packet); -static uint8_t computeNextMessageLength(MmrCanPacket *packet, uint8_t offset); +typedef struct { + CanHandle *handle; + MmrCanPacket *packet; + struct { + CanTxHeader tx; + MmrCanHeader mmr; + } headers; +} TransmissionParams; + + +static HalStatus send(TransmissionParams *tp); +static HalStatus sendNormal(TransmissionParams *tp); +static HalStatus sendMulti(TransmissionParams *tp); +static HalStatus sendSingleMultiFrame(TransmissionParams *tp); +static uint8_t computeFramesToSend(MmrCanPacket *packet); +static uint8_t computeNextMessageLength(MmrCanPacket *packet); +static void setMessageType(TransmissionParams *header, MmrCanMessageType type); +static void syncHeaders(TransmissionParams *tp); HalStatus MMR_CAN_Send(CanHandle *hcan, MmrCanPacket packet) { - CanTxHeader header = { - .IDE = CAN_ID_EXT, - .RTR = CAN_RTR_DATA, - .DLC = packet.length, - .ExtId = convertTo(uint32_t, packet.header), - .TransmitGlobalTime = DISABLE, + TransmissionParams tp = { + .handle = hcan, + .packet = &packet, + .headers.tx = { + .IDE = CAN_ID_EXT, + .RTR = CAN_RTR_DATA, + .DLC = packet.length, + .TransmitGlobalTime = DISABLE, + }, }; + syncHeaders(&tp); return packet.length <= MMR_CAN_MAX_DATA_LENGTH - ? sendNormal(hcan, &header, &packet) - : sendMulti(hcan, &header, &packet); + ? sendNormal(&tp) + : sendMulti(&tp); } -static HalStatus sendNormal( - CanHandle *hcan, - CanTxHeader *header, - MmrCanPacket *packet -) { - header->ExtId |= MMR_CAN_MESSAGE_TYPE_NORMAL; - return - HAL_CAN_AddTxMessage(hcan, header, packet->data, packet->mailbox); +static HalStatus sendNormal(TransmissionParams *tp) { + setMessageType(tp, MMR_CAN_MESSAGE_TYPE_NORMAL); + return send(tp); } -static HalStatus sendMulti( - CanHandle *hcan, - CanTxHeader *header, - MmrCanPacket *packet -) { +static HalStatus sendMulti(TransmissionParams *tp) { HalStatus status = HAL_OK; - uint8_t offset = 0; - uint8_t framesToSend = computeFramesToSend(packet); + uint8_t framesToSend = computeFramesToSend(tp->packet); - header->ExtId |= MMR_CAN_MESSAGE_TYPE_MULTI_FRAME; + setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME); do { bool isLastFrame = framesToSend <= 1; if (isLastFrame) { - header->ExtId |= MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END; + setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END); } - status |= - sendSingleMultiFrame(hcan, header, packet, &offset); + status |= sendSingleMultiFrame(tp); } while (framesToSend-- > 1 && status == HAL_OK); @@ -61,19 +67,32 @@ static HalStatus sendMulti( } -static HalStatus sendSingleMultiFrame( - CanHandle *hcan, - CanTxHeader *header, - MmrCanPacket *packet, - uint8_t *offset -) { - uint8_t *dataStart = packet->data + (*offset); - uint8_t length = computeNextMessageLength(packet, *offset); +static HalStatus sendSingleMultiFrame(TransmissionParams *tp) { + uint8_t length = + computeNextMessageLength(tp->packet); - header->DLC = length; - *offset += length; + tp->packet->length -= length; + tp->packet->data += length; + tp->headers.tx.DLC = length; - return HAL_CAN_AddTxMessage(hcan, header, dataStart, packet->mailbox); + return send(tp); +} + + +static HalStatus send(TransmissionParams *tp) { + syncHeaders(tp); + + return HAL_CAN_AddTxMessage( + tp->handle, + &tp->headers.tx, + tp->packet->data, + tp->packet->mailbox + ); +} + + +static void syncHeaders(TransmissionParams *tp) { + tp->headers.tx.ExtId = *MMR_CAN_HeaderToBits(&tp->headers.mmr); } @@ -109,22 +128,14 @@ static uint8_t computeFramesToSend(MmrCanPacket *packet) { /** * @brief * Returns the length for the next message, either - * 8 bytes or a lower value, keeping the offset into count. - * - * @example - * Given - * - a 17 bytes packet - * - an offset starting at 0 and supposedly incrementing - * of 8 after each call - * - * Three subsequent calls to this function will return - * First call -> min(17 - 0, 8) = min(17, 8) = 8 (bytes) - * Second call -> min(17 - 8, 8) = min(9, 8) = 8 (bytes) - * Third call -> min(17 - 16, 8) = min(1, 8) = 1 (byte) + * 8 bytes or a lower value. */ -static uint8_t computeNextMessageLength(MmrCanPacket *packet, uint8_t offset) { - uint8_t remainingBytes = packet->length - offset; +static uint8_t computeNextMessageLength(MmrCanPacket *packet) { return min( - remainingBytes, MMR_CAN_MAX_DATA_LENGTH + packet->length, MMR_CAN_MAX_DATA_LENGTH ); } + +static always_inline void setMessageType(TransmissionParams *tp, MmrCanMessageType type) { + tp->headers.mmr.messageType = type; +}