diff --git a/Inc/mmr_can.h b/Inc/mmr_can.h index 996e8cd..c3441d0 100644 --- a/Inc/mmr_can.h +++ b/Inc/mmr_can.h @@ -8,7 +8,7 @@ #include "mmr_can_types.h" #include "mmr_can_optimize.h" #include "mmr_can_binary_literals.h" -#include "mmr_can_timer_scs.h" +#include "mmr_can_scs_manager.h" #ifndef MMR_CAN_RX_FIFO #define MMR_CAN_RX_FIFO CAN_RX_FIFO0 @@ -163,6 +163,4 @@ MmrCanFilterSettings MMR_CAN_GetDefaultFilterSettings(); HalStatus MMR_CAN_Send(CanHandle *hcan, MmrCanPacket packet); HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result); -HalStatus MMR_CAN_SendSCS(CanHandle *hcan, MmrCanMessageId scsId, CanMailbox *mailbox, CanId senderId); - #endif /* INC_MMR_CAN_H_ */ diff --git a/Inc/mmr_can_header.h b/Inc/mmr_can_header.h index f442eea..79d5d9f 100644 --- a/Inc/mmr_can_header.h +++ b/Inc/mmr_can_header.h @@ -18,7 +18,7 @@ * Constants with lower values have an higher priority. */ typedef enum { - MMR_CAN_MESSAGE_ACK = B_(0001), + MMR_CAN_MESSAGE_TYPE_ACK = B_(0001), MMR_CAN_MESSAGE_TYPE_MULTI_FRAME = B_(0010), MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END = B_(0011), MMR_CAN_MESSAGE_TYPE_NORMAL = B_(0100), diff --git a/Inc/mmr_can_scs_manager.h b/Inc/mmr_can_scs_manager.h index 17b9184..43301cf 100644 --- a/Inc/mmr_can_scs_manager.h +++ b/Inc/mmr_can_scs_manager.h @@ -2,15 +2,32 @@ #define INC_MMR_CAN_SCS_MANAGER_H_ #include "mmr_can.h" -#include "mmr_can_timer_scs.h" + /** - * TODO: - * - GetCurrentTime - * - ACK - * - Reset timer - * - Setup method + * Scs_timer represents the max number of counter + * that need to checked w/current time */ +#ifndef MMR_CAN_SCS_ENTRIES_COUNT +#define MMR_CAN_SCS_ENTRIES_COUNT 5 +#endif + + +/** + * @brief + * Maximum timeout before first retransmission, + * in milliseconds + */ +#ifndef MMR_CAN_MAX_TIMEOUT +#define MMR_CAN_MAX_TIMEOUT 500 +#endif + + +/** + * It depends on how many bits the board devotes to the timer + * Check the datasheet + */ +typedef uint32_t TimerRange; /** @@ -18,20 +35,25 @@ * and allows to interface with the associated SCS's timer */ typedef struct { - MmrCanMessageId scsId; - CanId receiverId; + MmrCanHeader header; + TimerRange counter; int rtr; -} RTRresponse; +} MmrCanScsEntry; -/** - * It is used to iterate the RTRresponse array in the CheckSCS function - */ -static int counter; +typedef enum { + MMR_CAN_SCS_CHECK_OK, + MMR_CAN_SCS_CHECK_RTR, + MMR_CAN_SCS_CHECK_ERROR, +} MmrCanScsCheckResult; -bool MMR_CAN_SetRTRresponse(MmrCanMessageId scsId, CanId receiverId, int rtr); -TimerRange MMR_CAN_GetCurrentTime(); -void MMR_CAN_CheckSCS(); // What is necessary to do ritrasmission (mmr_can_send_scs) +bool MMR_CAN_MaybeHandleACK(MmrCanHeader header); +HalStatus MMR_CAN_HandleNextScs(CanHandle *hcan); +HalStatus MMR_CAN_SendSCS( + CanHandle *hcan, + MmrCanMessageId scsId, + CanId senderId +); -#endif // !INC_MMR_CAN_SCS_MANAGER_H_ \ No newline at end of file +#endif // !INC_MMR_CAN_SCS_MANAGER_H_ diff --git a/Inc/mmr_can_timer_scs.h b/Inc/mmr_can_timer_scs.h deleted file mode 100644 index 170922f..0000000 --- a/Inc/mmr_can_timer_scs.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef INC_MMR_CAN_TIMER_SCS_H_ -#define INC_MMR_CAN_TIMER_SCS_H_ - -#include "mmr_can_message_id.h" -#include "mmr_can_types.h" - -/** - * Scs_timer represents the max number of counter - * that need to checked w/current time - */ -#ifndef MMR_SCS_NR_TIMERS -#define MMR_SCS_NR_TIMERS 5 -#endif - -/** - * It depends on how many bits the board devotes to the timer - * Check the datasheet - */ -typedef uint32_t TimerRange; - -typedef struct { - MmrCanMessageId scsId; - CanId receiverId; - TimerRange counter; -} MmrTimerSCS; - - -/** - * All time units are to be considered as milliseconds (1ms) - */ -bool MMR_CAN_ClearTimerSCS(MmrCanMessageId scsId, CanId receiverId); -bool MMR_CAN_SetTimerSCS(MmrCanMessageId scsId, CanId receiverId, TimerRange currentTime); - -/** - * @brief The delay is taken individually so that the 'manager' - * can first check the ACK and eventually reset the associated arr_timer - * - * @param rtrResponse the 'manager' will have to manage an array of struct RTRresponse - * @param currentTime from __HAL_TIM_GET_COUNTER(&htimX) or directly from the CNT register - * @param thresholdDelay by rules 500ms - */ -bool MMR_CAN_GetTimerSCS(MmrCanMessageId scsId, CanId receiverId, int *rtr, TimerRange currentTime, TimerRange thresholdDelay); - - -#endif // !INC_MMR_CAN_TIMER_SCS_H_ diff --git a/Src/mmr_can_scs_manager.c b/Src/mmr_can_scs_manager.c index 3ab9a2a..37ad9c4 100644 --- a/Src/mmr_can_scs_manager.c +++ b/Src/mmr_can_scs_manager.c @@ -1,61 +1,137 @@ #include "mmr_can_scs_manager.h" -static RTRresponse arr_scs[MMR_SCS_NR_TIMERS]; +static MmrCanScsEntry __scsEntries[MMR_CAN_SCS_ENTRIES_COUNT]; -static RTRresponse* findResponse(MmrCanMessageId scsId, CanId receiverId); +static void maybeIncrementRTR(MmrCanScsEntry *entry); + +static MmrCanScsEntry* putEntry(MmrCanHeader header); +static MmrCanScsEntry* clearEntry(MmrCanHeader header); +static MmrCanScsEntry* findEntry(MmrCanHeader header); + +static TimerRange getCurrentTime(); +static HalStatus sendScs(CanHandle *hcan, MmrCanHeader header); +static MmrCanScsCheckResult checkScs(MmrCanScsEntry *entry); -bool SetRTRresponse(MmrCanMessageId scsId, CanId receiverId, int rtr) -{ - RTRresponse *response = findResponse(0, 0); - if (response == NULL) return false; +bool MMR_CAN_MaybeHandleACK(MmrCanHeader header) { + if (header.messageType != MMR_CAN_MESSAGE_TYPE_ACK) { + return false; + } - response->scsId = scsId; - response->receiverId = receiverId; - response->rtr = 0; + header.messageType = MMR_CAN_MESSAGE_TYPE_NORMAL; + MmrCanScsEntry *entry = findEntry(header); + if (entry == NULL) { + return false; + } - return MMR_CAN_SetTimerSCS(response->scsId, response->receiverId, MMR_CAN_GetCurrentTime); -} - -void CheckSCS() -{ - if (counter>=MMR_SCS_NR_TIMERS) counter=0; - - RTRresponse *_rtrResponse = &arr_scs[counter]; - - if(!MMR_CAN_GetTimerSCS(_rtrResponse->scsId, _rtrResponse->receiverId, &_rtrResponse->rtr, MMR_CAN_GetCurrentTime, 500)) - { - // do something - } - - counter++; - - if (_rtrResponse->rtr==1) - { - // Return ritrasmission - } - - if (_rtrResponse->rtr>1) - { - // Return Safe State - } + clearEntry(header); + return true; } -TimerRange MMR_CAN_GetCurrentTime() -{ +HalStatus MMR_CAN_SendSCS( + CanHandle *hcan, + MmrCanMessageId scsId, + CanId senderId +) { + MmrCanHeader header = { + .senderId = senderId, + .messageId = scsId, + .priority = MMR_CAN_MESSAGE_PRIORITY_HIGH, + }; + + putEntry(header); + return sendScs(hcan, header); +} + + +HalStatus MMR_CAN_HandleNextScs(CanHandle *hcan) { + static int counter = 0; + MmrCanScsEntry *entry = &__scsEntries[counter++ % MMR_CAN_SCS_ENTRIES_COUNT]; + + 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_Send(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 0; //TODO: HAL.... } -RTRresponse* findResponse(MmrCanMessageId scsId, CanId receiverId) { - int i = 0; - for (; i < MMR_SCS_NR_TIMERS; i++) { - RTRresponse *response = arr_scs + i; - if (response->scsId == scsId && response->receiverId == receiverId) { - return response; +void maybeIncrementRTR(MmrCanScsEntry *entry) { + TimerRange delay = + getCurrentTime() - 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; -} \ No newline at end of file +} diff --git a/Src/mmr_can_send_scs.c b/Src/mmr_can_send_scs.c deleted file mode 100644 index fd70002..0000000 --- a/Src/mmr_can_send_scs.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "mmr_can.h" -#include "mmr_can_scs_manager.h" - - -HalStatus MMR_CAN_SendSCS( - CanHandle *hcan, - MmrCanMessageId scsId, - CanMailbox *mailbox, - CanId senderId -) { - MmrCanPacket packet = { - .header = { - .senderId = senderId, - .messageId = scsId, - .priority = MMR_CAN_MESSAGE_PRIORITY_HIGH, - }, - .mailbox = mailbox, - .length = 0, - }; - - if(!MMR_CAN_SetRTRresponse()) - { - // do something - } - - return MMR_CAN_Send(hcan, packet); -} diff --git a/Src/mmr_can_timer_scs.c b/Src/mmr_can_timer_scs.c deleted file mode 100644 index 76ba3cd..0000000 --- a/Src/mmr_can_timer_scs.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "mmr_can_timer_scs.h" - -static MmrTimerSCS arr_timer[MMR_SCS_NR_TIMERS]; - -static MmrTimerSCS* findTimer(MmrCanMessageId scsId, CanId receiverId); - - -void MMR_CAN_InitTimerSCS() { - for (int i = 0; i < MMR_SCS_NR_TIMERS; i++) - { - arr_timer[i].scsId = 0; - arr_timer[i].receiverId = 0; - arr_timer[i].counter = 0; - } -} - - -bool MMR_CAN_ClearTimerSCS(MmrCanMessageId scsId, CanId receiverId) { - MmrTimerSCS *timer = findTimer(scsId, receiverId); - if (timer == NULL) return false; - - timer->scsId = 0; - timer->receiverId = 0; - timer->counter = 0; - return true; -} - - -bool MMR_CAN_SetTimerSCS(MmrCanMessageId scsId, CanId receiverId, TimerRange currentTime) { - MmrTimerSCS *timer = findTimer(0, 0); - if (timer == NULL) return false; - - timer->scsId = scsId; - timer->receiverId = receiverId; - timer->counter = currentTime; - return true; -} - - -bool MMR_CAN_GetTimerSCS(MmrCanMessageId scsId, CanId receiverId, int *rtr, TimerRange currentTime, TimerRange thresholdDelay) { - MmrTimerSCS *timer = findTimer(scsId, receiverId); - if (timer == NULL) return false; - - if (currentTime - timer->counter >= thresholdDelay) { - rtr++; - } - return true; -} - - -MmrTimerSCS* findTimer(MmrCanMessageId scsId, CanId receiverId) { - int i = 0; - for (; i < MMR_SCS_NR_TIMERS; i++) { - MmrTimerSCS *timer = arr_timer + i; - - if (timer->scsId == scsId && timer->receiverId == receiverId) { - return timer; - } - } - - return NULL; -}