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
This commit is contained in:
committed by
GitHub
parent
e7bb09478e
commit
174f5e8d76
+1
-1
@@ -78,7 +78,7 @@ typedef struct {
|
|||||||
* Represents a CAN message
|
* Represents a CAN message
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CanId senderId;
|
MmrCanHeader header;
|
||||||
void *store;
|
void *store;
|
||||||
} MmrCanMessage;
|
} MmrCanMessage;
|
||||||
|
|
||||||
|
|||||||
+14
-2
@@ -24,18 +24,30 @@ typedef enum {
|
|||||||
} MmrCanMessageType;
|
} 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
|
* @brief
|
||||||
* This struct encodes the values stored inside the
|
* This struct encodes the values stored inside the
|
||||||
* extended id field of a CAN packet.
|
* extended id field of a CAN packet.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t priority : 5;
|
MmrCanMessagePriority priority : 3;
|
||||||
uint32_t senderId : 23;
|
uint32_t dictionaryEntry : 10;
|
||||||
|
uint32_t senderId : 12;
|
||||||
MmrCanMessageType messageType : 4;
|
MmrCanMessageType messageType : 4;
|
||||||
} MmrCanHeader;
|
} MmrCanHeader;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t *MMR_CAN_HeaderToBits(MmrCanHeader *header);
|
||||||
|
MmrCanHeader *MMR_CAN_HeaderFromBits(uint32_t *bits);
|
||||||
|
|
||||||
bool MMR_CAN_IsMultiFrame(MmrCanHeader *header);
|
bool MMR_CAN_IsMultiFrame(MmrCanHeader *header);
|
||||||
bool MMR_CAN_IsMultiFrameEnd(MmrCanHeader *header);
|
bool MMR_CAN_IsMultiFrameEnd(MmrCanHeader *header);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef INC_MMR_CAN_QUEUE_H_
|
||||||
|
#define INC_MMR_CAN_QUEUE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#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_ */
|
||||||
@@ -1,6 +1,15 @@
|
|||||||
#include "mmr_can_header.h"
|
#include "mmr_can_header.h"
|
||||||
|
#include "mmr_can_util.h"
|
||||||
#include "mmr_can_optimize.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) {
|
bool MMR_CAN_IsMultiFrame(MmrCanHeader *header) {
|
||||||
return header->messageType == MMR_CAN_MESSAGE_TYPE_MULTI_FRAME;
|
return header->messageType == MMR_CAN_MESSAGE_TYPE_MULTI_FRAME;
|
||||||
|
|||||||
+10
-8
@@ -1,14 +1,11 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "mmr_can.h"
|
#include "mmr_can.h"
|
||||||
|
|
||||||
static HalStatus receiveOne(ReceptionParams *rp);
|
|
||||||
static HalStatus receiveAll(ReceptionParams *rp);
|
|
||||||
static bool headerIsMultiFrame(MmrCanHeader *header, CanId targetId);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CanHandle *handle;
|
CanHandle *handle;
|
||||||
uint8_t *result;
|
uint8_t *result;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CanRxHeader rx;
|
CanRxHeader rx;
|
||||||
MmrCanHeader mmr;
|
MmrCanHeader mmr;
|
||||||
@@ -18,6 +15,11 @@ typedef struct {
|
|||||||
} ReceptionParams;
|
} ReceptionParams;
|
||||||
|
|
||||||
|
|
||||||
|
static HalStatus receiveOne(ReceptionParams *rp);
|
||||||
|
static HalStatus receiveAll(ReceptionParams *rp);
|
||||||
|
static bool headerIsMultiFrame(MmrCanHeader *header, CanId targetId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Reads a CAN message and stores it inside the
|
* Reads a CAN message and stores it inside the
|
||||||
@@ -29,7 +31,7 @@ typedef struct {
|
|||||||
HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) {
|
HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) {
|
||||||
ReceptionParams rp = {
|
ReceptionParams rp = {
|
||||||
.handle = hcan,
|
.handle = hcan,
|
||||||
.result = interpretAs(uint8_t*, result->store),
|
.result = (uint8_t*)result->store,
|
||||||
.fifo = MMR_CAN_RX_FIFO,
|
.fifo = MMR_CAN_RX_FIFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result) {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->senderId = rp.headers.mmr.senderId;
|
result->header = rp.headers.mmr;
|
||||||
if (MMR_CAN_IsMultiFrame(&rp.headers.mmr)) {
|
if (MMR_CAN_IsMultiFrame(&rp.headers.mmr)) {
|
||||||
status |= receiveAll(&rp);
|
status |= receiveAll(&rp);
|
||||||
}
|
}
|
||||||
@@ -63,9 +65,9 @@ static HalStatus receiveAll(ReceptionParams *rp) {
|
|||||||
|
|
||||||
static HalStatus receiveOne(ReceptionParams *rp) {
|
static HalStatus receiveOne(ReceptionParams *rp) {
|
||||||
HalStatus status =
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+69
-58
@@ -3,57 +3,63 @@
|
|||||||
#include "mmr_can_util.h"
|
#include "mmr_can_util.h"
|
||||||
|
|
||||||
|
|
||||||
static HalStatus sendNormal(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet);
|
typedef struct {
|
||||||
static HalStatus sendMulti(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet);
|
CanHandle *handle;
|
||||||
static HalStatus sendSingleMultiFrame(CanHandle *hcan, CanTxHeader *header, MmrCanPacket *packet, uint8_t *offset);
|
MmrCanPacket *packet;
|
||||||
static uint8_t computeFramesToSend(MmrCanPacket *packet);
|
|
||||||
static uint8_t computeNextMessageLength(MmrCanPacket *packet, uint8_t offset);
|
|
||||||
|
|
||||||
|
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) {
|
HalStatus MMR_CAN_Send(CanHandle *hcan, MmrCanPacket packet) {
|
||||||
CanTxHeader header = {
|
TransmissionParams tp = {
|
||||||
.IDE = CAN_ID_EXT,
|
.handle = hcan,
|
||||||
.RTR = CAN_RTR_DATA,
|
.packet = &packet,
|
||||||
.DLC = packet.length,
|
.headers.tx = {
|
||||||
.ExtId = convertTo(uint32_t, packet.header),
|
.IDE = CAN_ID_EXT,
|
||||||
.TransmitGlobalTime = DISABLE,
|
.RTR = CAN_RTR_DATA,
|
||||||
|
.DLC = packet.length,
|
||||||
|
.TransmitGlobalTime = DISABLE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
syncHeaders(&tp);
|
||||||
|
|
||||||
return packet.length <= MMR_CAN_MAX_DATA_LENGTH
|
return packet.length <= MMR_CAN_MAX_DATA_LENGTH
|
||||||
? sendNormal(hcan, &header, &packet)
|
? sendNormal(&tp)
|
||||||
: sendMulti(hcan, &header, &packet);
|
: sendMulti(&tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HalStatus sendNormal(
|
static HalStatus sendNormal(TransmissionParams *tp) {
|
||||||
CanHandle *hcan,
|
setMessageType(tp, MMR_CAN_MESSAGE_TYPE_NORMAL);
|
||||||
CanTxHeader *header,
|
return send(tp);
|
||||||
MmrCanPacket *packet
|
|
||||||
) {
|
|
||||||
header->ExtId |= MMR_CAN_MESSAGE_TYPE_NORMAL;
|
|
||||||
return
|
|
||||||
HAL_CAN_AddTxMessage(hcan, header, packet->data, packet->mailbox);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HalStatus sendMulti(
|
static HalStatus sendMulti(TransmissionParams *tp) {
|
||||||
CanHandle *hcan,
|
|
||||||
CanTxHeader *header,
|
|
||||||
MmrCanPacket *packet
|
|
||||||
) {
|
|
||||||
HalStatus status = HAL_OK;
|
HalStatus status = HAL_OK;
|
||||||
uint8_t offset = 0;
|
uint8_t framesToSend = computeFramesToSend(tp->packet);
|
||||||
uint8_t framesToSend = computeFramesToSend(packet);
|
|
||||||
|
|
||||||
header->ExtId |= MMR_CAN_MESSAGE_TYPE_MULTI_FRAME;
|
setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME);
|
||||||
do {
|
do {
|
||||||
bool isLastFrame = framesToSend <= 1;
|
bool isLastFrame = framesToSend <= 1;
|
||||||
if (isLastFrame) {
|
if (isLastFrame) {
|
||||||
header->ExtId |= MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END;
|
setMessageType(tp, MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
status |=
|
status |= sendSingleMultiFrame(tp);
|
||||||
sendSingleMultiFrame(hcan, header, packet, &offset);
|
|
||||||
}
|
}
|
||||||
while (framesToSend-- > 1 && status == HAL_OK);
|
while (framesToSend-- > 1 && status == HAL_OK);
|
||||||
|
|
||||||
@@ -61,19 +67,32 @@ static HalStatus sendMulti(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HalStatus sendSingleMultiFrame(
|
static HalStatus sendSingleMultiFrame(TransmissionParams *tp) {
|
||||||
CanHandle *hcan,
|
uint8_t length =
|
||||||
CanTxHeader *header,
|
computeNextMessageLength(tp->packet);
|
||||||
MmrCanPacket *packet,
|
|
||||||
uint8_t *offset
|
|
||||||
) {
|
|
||||||
uint8_t *dataStart = packet->data + (*offset);
|
|
||||||
uint8_t length = computeNextMessageLength(packet, *offset);
|
|
||||||
|
|
||||||
header->DLC = length;
|
tp->packet->length -= length;
|
||||||
*offset += 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
|
* @brief
|
||||||
* Returns the length for the next message, either
|
* Returns the length for the next message, either
|
||||||
* 8 bytes or a lower value, keeping the offset into count.
|
* 8 bytes or a lower value.
|
||||||
*
|
|
||||||
* @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)
|
|
||||||
*/
|
*/
|
||||||
static uint8_t computeNextMessageLength(MmrCanPacket *packet, uint8_t offset) {
|
static uint8_t computeNextMessageLength(MmrCanPacket *packet) {
|
||||||
uint8_t remainingBytes = packet->length - offset;
|
|
||||||
return min(
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user