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_scs_manager.c
T
Nicola Gutierrez 9dfb76b9de Test HandleNext OK
2022-02-19 13:56:15 +01:00

158 lines
3.2 KiB
C

#include "mmr_can_scs_manager.h"
static MmrCanScsEntry __scsEntries[MMR_CAN_SCS_ENTRIES_COUNT];
static void maybeIncrementRTR(MmrCanScsEntry *entry);
static MmrCanScsEntry* putEntry(MmrCanHeader header);
static MmrCanScsEntry* clearEntry(MmrCanHeader header);
static MmrCanScsEntry* findEntry(MmrCanHeader header);
static TimerRange getCurrentTime();
HalStatus sendScs(CanHandle *hcan, MmrCanHeader header);
static MmrCanScsCheckResult checkScs(MmrCanScsEntry *entry);
bool MMR_CAN_MaybeHandleAck(MmrCanHeader header) {
if (header.messageType != MMR_CAN_MESSAGE_TYPE_ACK) {
return false;
}
header.messageType = MMR_CAN_MESSAGE_TYPE_SCS;
MmrCanScsEntry *entry = findEntry(header);
if (entry == NULL) {
return false;
}
clearEntry(header);
return true;
}
HalStatus MMR_CAN_SendAck(
CanHandle *hcan,
MmrCanHeader originalHeader
) {
originalHeader.messageType = MMR_CAN_MESSAGE_TYPE_ACK;
return sendScs(hcan, originalHeader);
}
HalStatus MMR_CAN_SendScs(
CanHandle *hcan,
MmrCanMessageId scsId,
CanId senderId
) {
MmrCanHeader header = {
.senderId = senderId,
.messageId = scsId,
.priority = MMR_CAN_MESSAGE_PRIORITY_HIGH,
.messageType = MMR_CAN_MESSAGE_TYPE_SCS,
};
if (putEntry(header) == NULL) {
return HAL_ERROR;
}
return sendScs(hcan, header);
}
HalStatus MMR_CAN_HandleNextScs(CanHandle *hcan) {
static int counter = 0;
MmrCanScsEntry *entry = &__scsEntries[counter];
counter++;
counter %= MMR_CAN_SCS_ENTRIES_COUNT;
if (MMR_CAN_HeaderToBits(entry->header) == 0) {
return HAL_OK;
}
switch (checkScs(entry)) {
case MMR_CAN_SCS_CHECK_ERROR: return HAL_ERROR;
case MMR_CAN_SCS_CHECK_OK: return HAL_OK;
default: break;
}
entry->counter = getCurrentTime();
return sendScs(hcan, entry->header);
}
HalStatus sendScs(CanHandle *hcan, MmrCanHeader header) {
static CanMailbox scsMailbox = 0;
MmrCanPacket packet = {
.header = header,
.mailbox = &scsMailbox,
.length = 0,
};
return MMR_CAN_SendNoTamper(hcan, packet);
}
MmrCanScsCheckResult checkScs(MmrCanScsEntry *entry) {
maybeIncrementRTR(entry);
return
entry->rtr == 1 ? MMR_CAN_SCS_CHECK_RTR :
entry->rtr > 1 ? MMR_CAN_SCS_CHECK_ERROR :
MMR_CAN_SCS_CHECK_OK;
}
TimerRange getCurrentTime() {
return __mmr_can_tickProvider();
}
void maybeIncrementRTR(MmrCanScsEntry *entry) {
TimerRange now = getCurrentTime();
TimerRange delay = now - entry->counter;
if (delay >= MMR_CAN_MAX_TIMEOUT) {
entry->rtr++;
}
}
MmrCanScsEntry* putEntry(MmrCanHeader header) {
MmrCanScsEntry *entry = findEntry((MmrCanHeader){});
if (entry == NULL) {
return NULL;
}
*entry = (MmrCanScsEntry){
.header = header,
.counter = getCurrentTime(),
};
return entry;
}
MmrCanScsEntry* clearEntry(MmrCanHeader header) {
MmrCanScsEntry *entry = findEntry(header);
if (entry == NULL) {
return NULL;
}
*entry = (MmrCanScsEntry){};
return entry;
}
MmrCanScsEntry* findEntry(MmrCanHeader header) {
uint32_t target = MMR_CAN_HeaderToBits(header);
uint32_t i = 0;
for (; i < MMR_CAN_SCS_ENTRIES_COUNT; i++) {
MmrCanScsEntry *entry = __scsEntries + i;
uint32_t curr = MMR_CAN_HeaderToBits(entry->header);
if (curr == target) {
return entry;
}
}
return NULL;
}