From f34e2a1fc6c4f82ea827fba456210f1c55a26ee6 Mon Sep 17 00:00:00 2001 From: Stefano Calabretti Date: Tue, 17 May 2022 14:17:50 +0200 Subject: [PATCH] WIP --- Inc/mmr_can.h | 27 +++++- Inc/mmr_can_header.h | 2 - Inc/mmr_can_types.h | 1 + Src/mmr_can_header.c | 13 +-- Src/mmr_can_receive.c | 77 ++-------------- Src/mmr_can_send.c | 209 +++++++++++------------------------------- 6 files changed, 92 insertions(+), 237 deletions(-) diff --git a/Inc/mmr_can.h b/Inc/mmr_can.h index b85fa92..f29ef81 100644 --- a/Inc/mmr_can.h +++ b/Inc/mmr_can.h @@ -46,6 +46,15 @@ typedef uint32_t (*MmrCanTickProvider)(); typedef uint8_t CanRxBuffer[MMR_CAN_MAX_DATA_LENGTH]; +typedef struct MmrCan { + CanId id; + CanHandle *handle; + CanFifo fifo; + CanMailbox mailboxes[MAILBOXES_COUNT]; + uint8_t currentMailbox; +} MmrCan; + + typedef struct MmrCanFilterSettings { bool enabled; @@ -115,7 +124,7 @@ typedef struct MmrCanFilterSettings { */ typedef struct MmrCanPacket { MmrCanHeader header; - uint8_t *data; + void *data; uint8_t length; } MmrCanPacket; @@ -173,6 +182,18 @@ typedef struct MmrCanMessage { extern MmrCanTickProvider __mmr_can_tickProvider; + +MmrCan MMR_CAN_Create(CanHandle *hcan, CanFifo rxFifo); +HalStatus MMR_CAN_Start(MmrCan *can); +HalStatus MMR_CAN_EnableFilter(MmrCan *can, CanFilterMask mask, CanFilterBank bank); + +HalStatus MMR_CAN_SendString(MmrCan *can, MmrCanMessageId msgId, const char *data); +HalStatus MMR_CAN_SendInt(MmrCan *can, MmrCanMessageId msgId, int data); +HalStatus MMR_CAN_SendFloat(MmrCan *can, MmrCanMessageId msgId, float data); +HalStatus MMR_CAN_SendRaw(MmrCan *can, MmrCanMessageId msgId, void *data, uint8_t length); +HalStatus MMR_CAN_SendPacket(MmrCan *can, MmrCanPacket packet); + + /** * @brief * Sets the tick provider. @@ -235,7 +256,7 @@ HalStatus MMR_CAN_SendNoTamper(CanHandle *hcan, MmrCanPacket packet); * @brief * Tries to receive a message. */ -MmrResult MMR_CAN_TryReceive(CanHandle *hcan, MmrCanMessage *result); +MmrResult MMR_CAN_TryReceive(MmrCan *can, MmrCanMessage *result); /** * @brief @@ -245,6 +266,6 @@ MmrResult MMR_CAN_TryReceive(CanHandle *hcan, MmrCanMessage *result); * If a multi-frame message is received, this function will block * and read every frame for that particular message. */ -HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result); +HalStatus MMR_CAN_Receive(MmrCan *can, MmrCanMessage *result); #endif /* INC_MMR_CAN_H_ */ diff --git a/Inc/mmr_can_header.h b/Inc/mmr_can_header.h index b6becf5..87722cb 100644 --- a/Inc/mmr_can_header.h +++ b/Inc/mmr_can_header.h @@ -79,7 +79,5 @@ MmrCanHeader MMR_CAN_HeaderFromBits(uint32_t bits); * Tells wether the given header represents an SCS. */ bool MMR_CAN_IsHeaderScs(MmrCanHeader header); -bool MMR_CAN_IsMultiFrame(MmrCanHeader header); -bool MMR_CAN_IsMultiFrameEnd(MmrCanHeader header); #endif /* INC_MMR_CAN_HEADER_H_ */ diff --git a/Inc/mmr_can_types.h b/Inc/mmr_can_types.h index 657e379..a71f97d 100644 --- a/Inc/mmr_can_types.h +++ b/Inc/mmr_can_types.h @@ -12,6 +12,7 @@ typedef uint32_t CanId; typedef uint32_t CanMailbox; +typedef uint32_t CanFifo; /** * @brief diff --git a/Src/mmr_can_header.c b/Src/mmr_can_header.c index f3e4d1d..81cee55 100644 --- a/Src/mmr_can_header.c +++ b/Src/mmr_can_header.c @@ -2,6 +2,11 @@ #include "mmr_can_util.h" #include "mmr_can_optimize.h" +struct MmrCanHeader { + +}; + + uint32_t MMR_CAN_HeaderToBits(MmrCanHeader header) { return 0 | ((uint32_t)header.priority << 26) @@ -25,11 +30,3 @@ MmrCanHeader MMR_CAN_HeaderFromBits(uint32_t bits) { bool MMR_CAN_IsHeaderScs(MmrCanHeader header) { return header.messageType == MMR_CAN_MESSAGE_TYPE_SCS; } - -bool MMR_CAN_IsMultiFrame(MmrCanHeader header) { - return header.messageType == MMR_CAN_MESSAGE_TYPE_MULTI_FRAME; -} - -bool MMR_CAN_IsMultiFrameEnd(MmrCanHeader header) { - return header.messageType == MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END; -} diff --git a/Src/mmr_can_receive.c b/Src/mmr_can_receive.c index 8480b85..428cc39 100644 --- a/Src/mmr_can_receive.c +++ b/Src/mmr_can_receive.c @@ -2,25 +2,7 @@ #include "mmr_can.h" -typedef struct { - CanHandle *handle; - uint8_t *result; - - struct { - CanRxHeader rx; - MmrCanHeader mmr; - } headers; - - uint8_t fifo; -} ReceptionParams; - - -static HalStatus receiveOne(ReceptionParams *rp); -static HalStatus receiveAll(ReceptionParams *rp); -static bool headerIsMultiFrame(MmrCanHeader header, CanId targetId); - - -MmrResult MMR_CAN_TryReceive(CanHandle *hcan, MmrCanMessage *result) { +MmrResult MMR_CAN_TryReceive(MmrCan *can, MmrCanMessage *result) { size_t pendingMessages = HAL_CAN_GetRxFifoFillLevel(hcan, MMR_CAN_RX_FIFO); @@ -34,58 +16,15 @@ MmrResult MMR_CAN_TryReceive(CanHandle *hcan, MmrCanMessage *result) { } -HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) { - ReceptionParams rp = { - .handle = hcan, - .result = (uint8_t*)result->store, - .fifo = MMR_CAN_RX_FIFO, - }; - - HalStatus status = receiveOne(&rp); - if (status != HAL_OK) { - return status; - } - - result->header = rp.headers.mmr; - if (MMR_CAN_IsMultiFrame(rp.headers.mmr)) { - status |= receiveAll(&rp); - } - - return status; -} - - -static HalStatus receiveAll(ReceptionParams *rp) { - CanId targetId = rp->headers.mmr.senderId; - HalStatus status = HAL_OK; - do { - rp->result += MMR_CAN_MAX_DATA_LENGTH; - status |= receiveOne(rp); - } - while ( - headerIsMultiFrame(rp->headers.mmr, targetId) && status == HAL_OK - ); - - return status; -} - - -static HalStatus receiveOne(ReceptionParams *rp) { +HalStatus MMR_CAN_Receive(MmrCan *can, MmrCanMessage *result) { + CanRxHeader rxHeader = {}; HalStatus status = HAL_CAN_GetRxMessage( - rp->handle, - rp->fifo, - &rp->headers.rx, - rp->result + can->handle, + can->fifo, + &rxHeader, + result->store ); - rp->headers.mmr = MMR_CAN_HeaderFromBits(rp->headers.rx.ExtId); + result->header = MMR_CAN_HeaderFromBits(rxHeader.ExtId); return status; } - - -static bool headerIsMultiFrame(MmrCanHeader header, CanId targetId) { - return - MMR_CAN_IsMultiFrame(header) && - !MMR_CAN_IsMultiFrameEnd(header) && - header.senderId == targetId; -} diff --git a/Src/mmr_can_send.c b/Src/mmr_can_send.c index 6c4d613..41f2356 100644 --- a/Src/mmr_can_send.c +++ b/Src/mmr_can_send.c @@ -2,174 +2,73 @@ #include "mmr_can.h" #include "mmr_can_util.h" - -typedef struct { - CanHandle *handle; - MmrCanPacket *packet; - - struct { - CanTxHeader tx; - MmrCanHeader mmr; - } headers; -} TransmissionParams; - - -static TransmissionParams buildParams(CanHandle *hcan, MmrCanPacket *packet); -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); -static CanMailbox *getNextMailbox(); - - #define MAILBOXES_COUNT 3 -static CanMailbox __mailboxes[MAILBOXES_COUNT] = {}; -static uint8_t __currentMailbox = 0; +static MmrCanHeader buildDefaultHeader(MmrCan *can, MmrCanMessageId msgId); +static CanMailbox *getNextMailbox(MmrCan *can); -HalStatus MMR_CAN_Send(CanHandle *hcan, MmrCanPacket packet) { - TransmissionParams tp = - buildParams(hcan, &packet); +HalStatus MMR_CAN_SendString(MmrCan *can, MmrCanMessageId msgId, const char *data) { + uint8_t len = + strnlen(data, MMR_CAN_MAX_DATA_LENGTH); - syncHeaders(&tp); - return packet.length <= MMR_CAN_MAX_DATA_LENGTH - ? sendNormal(&tp) - : sendMulti(&tp); + return MMR_CAN_SendRaw(can, msgId, &data, len); +} + +HalStatus MMR_CAN_SendInt(MmrCan *can, MmrCanMessageId msgId, int data) { + return MMR_CAN_SendRaw(can, msgId, &data, sizeof(data)) +} + +HalStatus MMR_CAN_SendFloat(MmrCan *can, MmrCanMessageId msgId, float data) { + return MMR_CAN_SendRaw(can, msgId, &data, sizeof(data)); } -HalStatus MMR_CAN_SendNoTamper(CanHandle *hcan, MmrCanPacket packet) { - TransmissionParams tp = - buildParams(hcan, &packet); - - return send(&tp); +HalStatus MMR_CAN_SendRaw( + MmrCan *can, + MmrCanMessageId msgId, + void *data, + uint8_t length +) { + return MMR_CAN_SendPacket(can, (MmrCanPacket){ + .header = buildDefaultHeader(can, msgId), + .data = data, + .length = length, + }); } -static TransmissionParams buildParams(CanHandle *hcan, MmrCanPacket *packet) { - return (TransmissionParams) { - .handle = hcan, - .packet = packet, - .headers.mmr = packet->header, - .headers.tx = { - .IDE = CAN_ID_EXT, - .RTR = CAN_RTR_DATA, - .DLC = packet->length, - .TransmitGlobalTime = DISABLE, - }, +HalStatus MMR_CAN_SendPacket(MmrCan *can, MmrCanPacket packet) { + CanTxHeader txHeader = { + .ExtId = MMR_CAN_HeaderToBits(packet.header), + .IDE = CAN_ID_EXT, + .RTR = CAN_RTR_DATA, + .DLC = packet->length, + .TransmitGlobalTime = DISABLE, + }; + + return HAL_CAN_AddTxMessage( + can->handle, + &txHeader, + (uint8_t*)packet.data, + getNextMailbox(can) + ); +} + + +MmrCanHeader buildDefaultHeader(MmrCan *can, MmrCanMessageId msgId) { + return (MmrCanHeader){ + .messageId = msgId, + .senderId = can->id, + .priority = MMR_CAN_MESSAGE_PRIORITY_NORMAL, + .messageType = MMR_CAN_MESSAGE_TYPE_NORMAL, }; } -static HalStatus sendNormal(TransmissionParams *tp) { - setMessageType(tp, MMR_CAN_MESSAGE_TYPE_NORMAL); - return send(tp); -} - - -static HalStatus sendMulti(TransmissionParams *tp) { - HalStatus status = HAL_OK; - uint8_t framesToSend = computeFramesToSend(tp->packet); - - setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME); - do { - bool isLastFrame = framesToSend <= 1; - if (isLastFrame) { - setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END); - } - - status |= sendSingleMultiFrame(tp); - } - while (framesToSend-- > 1 && status == HAL_OK); - - return status; -} - - -static HalStatus sendSingleMultiFrame(TransmissionParams *tp) { - uint8_t length = - computeNextMessageLength(tp->packet); - - tp->headers.tx.DLC = length; - tp->packet->length -= length; - - HalStatus result = send(tp); - - tp->packet->data += length; - return result; -} - - -static HalStatus send(TransmissionParams *tp) { - syncHeaders(tp); - - return HAL_CAN_AddTxMessage( - tp->handle, - &tp->headers.tx, - tp->packet->data, - getNextMailbox() - ); -} - - -static CanMailbox *getNextMailbox() { - __currentMailbox++; - __currentMailbox %= MAILBOXES_COUNT; - - return __mailboxes + __currentMailbox; -} - - -static void syncHeaders(TransmissionParams *tp) { - tp->headers.tx.ExtId = MMR_CAN_HeaderToBits(tp->headers.mmr); -} - - -/** - * @brief - * Computes the frames that will need to be sent for a packet. - * - * For example, if a packet has 15 bytes, the function will return - * 2, as one packet is needed for the first 8 bytes and another is - * needed for the remaining 7. - * - * @example - * The computation is pretty simple - * Given - * length = 17 (bytes) - * We'll have - * framesToSend = 17 / 8 = 2 (frames) - * remainder = 17 % 8 = 1 (bytes) - * maybeOneForRemainder = 1 > 0 = 1 (frame) - * ------------------------------------------- - * result = 2 + 1 = 3 (frames) - */ -static uint8_t computeFramesToSend(MmrCanPacket *packet) { - uint8_t length = packet->length; - uint8_t framesToSend = length / MMR_CAN_MAX_DATA_LENGTH; - uint8_t remainder = length % MMR_CAN_MAX_DATA_LENGTH; - uint8_t maybeOneForRemainder = remainder > 0; - - return framesToSend + maybeOneForRemainder; -} - - -/** - * @brief - * Returns the length for the next message, either - * 8 bytes or a lower value. - */ -static uint8_t computeNextMessageLength(MmrCanPacket *packet) { - return min( - packet->length, MMR_CAN_MAX_DATA_LENGTH - ); -} - -static always_inline void setMessageType(TransmissionParams *tp, MmrCanMessageType type) { - tp->headers.mmr.messageType = type; +static CanMailbox *getNextMailbox(MmrCan *can) { + can->currentMailbox++; + can->currentMailbox %= MAILBOXES_COUNT; + + return can->mailboxes + can->currentMailbox; }