From 4ac0afc01071275b3288f48281e7b381bb266e45 Mon Sep 17 00:00:00 2001 From: Stefano Calabretti Date: Tue, 15 Feb 2022 19:33:22 +0100 Subject: [PATCH] Add documentation --- Inc/mmr_can.h | 69 +++++++++++++++++++++++++++++++++++++++- Inc/mmr_can_header.h | 20 +++++++++--- Inc/mmr_can_message_id.h | 26 ++++++++++++++- Inc/mmr_can_optimize.h | 10 ++++++ Inc/mmr_can_timer_scs.h | 4 +-- Inc/mmr_can_types.h | 5 ++- Inc/mmr_can_util.h | 42 ++++++++++++++++++++++-- 7 files changed, 164 insertions(+), 12 deletions(-) diff --git a/Inc/mmr_can.h b/Inc/mmr_can.h index 75b7499..996e8cd 100644 --- a/Inc/mmr_can.h +++ b/Inc/mmr_can.h @@ -66,6 +66,43 @@ typedef struct { } MmrCanFilterSettings; +/** + * @brief + * A packet that can be sent over a CAN + * network. + * + * @example + * typedef struct { + * int x; + * int y; + * } Point; + * + * HalStatus send(Point point) { + * static CanMailbox mailbox = 0; + * + * MmrCanPacket packet = { + * .header = { + * .priority = MMR_CAN_MESSAGE_PRIORITY_NORMAL, + * .messageId = MMR_CAN_EXAMPLES_POINT, + * .senderId = 0xXXX, + * }, + * .mailbox = &mailbox, + * .data = (uint8_t*)&point, + * .length = sizeof(point), + * }; + * + * return MMR_CAN_Send(&hcan, packet); + * } + * + * int main() { + * Point p = {10, 20}; + * if (send(p) != HAL_OK) { + * Error_Handler(); + * } + * + * // 'p' has been sent. + * } + */ typedef struct { MmrCanHeader header; CanMailbox *mailbox; @@ -76,7 +113,37 @@ typedef struct { /** * @brief - * Represents a CAN message + * A message received over a CAN network. + * + * @example + * typedef struct { + * int x; + * int y; + * } Point; + * + * HalStatus receive(Point *result) { + * MmrCanMessage message = { + * .store = result, + * }; + * + * HalStatus result = MMR_CAN_Receive(&hcan, &message); + * bool isAPoint = message.header.messageId == MMR_CAN_EXAMPLES_POINT; + * if (!isAPoint) { + * return HAL_ERROR; + * } + * + * return result; + * } + * + * int main() { + * Point p = {}; + * if (receive(&p) != HAL_OK) { + * Error_Handler(); + * } + * + * // here 'p' has been populated and can + * // be used. + * } */ typedef struct { MmrCanHeader header; diff --git a/Inc/mmr_can_header.h b/Inc/mmr_can_header.h index 7e22dcf..f442eea 100644 --- a/Inc/mmr_can_header.h +++ b/Inc/mmr_can_header.h @@ -12,11 +12,10 @@ * portion of the CAN bus message (that is, the lower 5 bits * of the standard id) * - * They are used to check if a message is either standalone - * or split into multiple frames + * They are used to check if a message is either standalone, an + * acknowledgement or split into multiple frames * - * When the priority and id fields are the same, multi-frame - * messages have a higher priority over normal ones + * Constants with lower values have an higher priority. */ typedef enum { MMR_CAN_MESSAGE_ACK = B_(0001), @@ -47,7 +46,20 @@ typedef struct { } MmrCanHeader; +/** + * @brief + * Converts an MmrCanHeader to bits. + * That is, a 32bits integer with the first + * 3 bits set to zero and the remaining 29 containing the + * extended id + */ uint32_t *MMR_CAN_HeaderToBits(MmrCanHeader *header); + +/** + * @brief + * Converts a 32bits integer to an MmrCanHeader. + * The left-most 3 bits must be of padding. + */ MmrCanHeader *MMR_CAN_HeaderFromBits(uint32_t *bits); bool MMR_CAN_IsMultiFrame(MmrCanHeader *header); diff --git a/Inc/mmr_can_message_id.h b/Inc/mmr_can_message_id.h index e41740d..d917f8d 100644 --- a/Inc/mmr_can_message_id.h +++ b/Inc/mmr_can_message_id.h @@ -24,10 +24,34 @@ typedef enum { } MmrCanMessageIdType; +/** + * @brief + * Returns the 3 bits representing + * the MmrCanMessageIdType. + */ uint8_t MMR_CAN_GetMessageIdType(MmrCanMessageId msgId); + +/** + * @brief + * Returns the 7 bits representing + * the message id's subtype. + */ uint8_t MMR_CAN_GetMessageIdSubtype(MmrCanMessageId msgId); +/** + * @brief + * Tells wether the provided message + * is of the given id type. + * + * E.g. if a message is an SCS. + */ bool MMR_CAN_IsMessageIdOfType(MmrCanMessageId msgId, MmrCanMessageIdType type); + +/** + * @brief + * Tells wether the given message id is + * represents an SCS. + */ bool MMR_CAN_IsMessageIdSCS(MmrCanMessageId msgId); @@ -50,7 +74,7 @@ enum MmrCanMessageId { MMR_CAN_MESSAGE_ID_SCS_AS_READY, MMR_CAN_MESSAGE_ID_SCS_AS_DRIVING, MMR_CAN_MESSAGE_ID_SCS_AS_OFF, - + MMR_CAN_MESSAGE_ID_SCS_AM_MANUAL_DRIVING, MMR_CAN_MESSAGE_ID_SCS_AM_ACCELERATION, MMR_CAN_MESSAGE_ID_SCS_AM_SKIDPAD, diff --git a/Inc/mmr_can_optimize.h b/Inc/mmr_can_optimize.h index a3094b2..341b77c 100644 --- a/Inc/mmr_can_optimize.h +++ b/Inc/mmr_can_optimize.h @@ -2,6 +2,16 @@ #define INC_MMR_CAN_OPTIMIZE_H_ #ifdef __GNUC__ +/** + * @brief + * Tells the compiler that the given method + * must always be inlined. + * + * @example + * static always_inline int min(int a, int b) { + * return a < b ? a : b; + * } + */ #define always_inline inline __attribute__((always_inline)) #else #define always_inline inline diff --git a/Inc/mmr_can_timer_scs.h b/Inc/mmr_can_timer_scs.h index 6a13ba9..d9bcf29 100644 --- a/Inc/mmr_can_timer_scs.h +++ b/Inc/mmr_can_timer_scs.h @@ -41,7 +41,7 @@ typedef struct { /** - * All time units are to be considered as microseconds ( 1ms ) + * 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); @@ -57,4 +57,4 @@ bool MMR_CAN_SetTimerSCS(MmrCanMessageId scsId, CanId receiverId, TimerRange cur bool MMR_CAN_GetTimerSCS(RTRresponse *rtrResponse, TimerRange currentTime, TimerRange thresholdDelay); -#endif // !INC_MMR_CAN_TIMER_SCS_H_ \ No newline at end of file +#endif // !INC_MMR_CAN_TIMER_SCS_H_ diff --git a/Inc/mmr_can_types.h b/Inc/mmr_can_types.h index f490cb6..3b7f115 100644 --- a/Inc/mmr_can_types.h +++ b/Inc/mmr_can_types.h @@ -8,6 +8,7 @@ typedef uint32_t CanId; typedef uint32_t CanMailbox; /** + * @brief * A filter mask for the CANbus. * It acts like a subnet mask, filtering the ids that * do not match it. @@ -20,12 +21,14 @@ typedef uint32_t CanMailbox; typedef uint32_t CanFilterMask; /** + * @brief * Stores a value from CAN_filter_FIFO * That is, CAN_FILTER_FIFOx */ typedef uint8_t CanFilterFifo; -/** +/** + * @brief * Represents a filter bank. * The values must be in the range [0, 27] */ diff --git a/Inc/mmr_can_util.h b/Inc/mmr_can_util.h index 06929e9..723dfa3 100644 --- a/Inc/mmr_can_util.h +++ b/Inc/mmr_can_util.h @@ -4,16 +4,52 @@ #include #include +/** + * @brief + * Returns the size of the given array. + * + * This only works on static arrays declared + * within the current scope, that is: + * int main() { + * int arr[] = {1, 2, 3}; + * int len = sizeofarray(arr); + * } + */ #define sizeofarray(array) \ (sizeof(array) / sizeof(*(array))) +/** + * @brief + * Returns the length of a statically, non const ptr, declared + * string. + * That is: + * int main() { + * char str[] = "abc"; + * int len = stringArrayLength(str); + * } + */ #define stringArrayLength(array) \ stringBufferLength((array), sizeofarray(array)) +/** + * @brief + * Returns the length of a string buffer. + * Its format must be in bytes, so it could be: + * const char* + * char* + * uint8_t* + * etc... + */ #define stringBufferLength(pbuffer, maxLen) \ strnlen((const char*)(pbuffer), maxLen) -#define min(a, b) ((a) < (b) ? a : b); +/** + * @brief + * Returns the minimum between the + * two given values. + * E.g. min(1, 2) == 1 // true + */ +#define min(a, b) ((a) < (b) ? a : b) #define mask(value, bits) (value & bits) #define convertTo(resultType, lvalue) (*interpretAs(resultType*, &(lvalue))) #define interpretAs(resultType, lvalue) ((resultType)(lvalue)) @@ -26,10 +62,10 @@ * Either * - Error: the computation resulted in error * - Pending: the computation is still undergoing - * - Completed: the computation has completed succesfully + * - Completed: the computation has completed successfully * and its results can be read * - * Asynchronous logig can be easily implemented using State Machines + * Asynchronous logic can be easily implemented using State Machines */ typedef enum { MMR_ASYNC_RESULT_ERROR,