This repository has been archived on 2026-02-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
can/Src/mmr_can_receive.c
T
Stefano Calabretti ed2a26fbc9 Better parameter handling (#6)
* Add rx event handlers

* Fix compile errors and add constness

* Pass sender id

* Change api interface

* Revert changes

* Add filter fifo

* Add default setup

* Add receive function

* Remove interrupt activation

* Activate RX interrupts

* Merge remote changes

* Add event list constructor

* Fix compilation bug

* Send and receive multiple frames

* Refactor

* Refactor

* Fix compile error

* Use known syntax

* Refactor

* Provide storage

* Add frame end

* Add some documentation

* Turn macros into functions

* Refactor

* Refactor

* Fix compile error

* Use ExtendedIds

* Fix reception bug (fixes #4)

* Add packet headers

* Refactor

Co-authored-by: Riccardo998 <riccardo.storchi98@gmail.com>
2021-12-20 15:12:57 +01:00

79 lines
1.7 KiB
C

#include <stdbool.h>
#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;
} headers;
uint8_t fifo;
} ReceptionParams;
/**
* @brief
* Reads a CAN message and stores it inside the
* given MmrCanMessage struct.
*
* 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) {
ReceptionParams rp = {
.handle = hcan,
.result = interpretAs(uint8_t*, result->store),
.fifo = MMR_CAN_RX_FIFO,
};
HalStatus status = receiveOne(&rp);
if (status != HAL_OK) {
return status;
}
result->senderId = rp.headers.mmr.senderId;
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 status =
HAL_CAN_GetRxMessage(rp->hcan, rp->fifo, &(rp->headers.rx), rp->result);
rp->headers.mmr = convertTo(MmrCanHeader, header->ExtId);
return status;
}
static always_inline bool headerIsMultiFrame(MmrCanHeader *header, CanId targetId) {
return
MMR_CAN_IsMultiFrame(header) &&
!MMR_CAN_IsMultiFrameEnd(header) &&
header->senderId == targetId;
}