Multiple frames implementation (#2)
* 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 Co-authored-by: Riccardo998 <riccardo.storchi98@gmail.com>
This commit is contained in:
committed by
GitHub
parent
90d1836dfa
commit
7b09401b00
+44
-14
@@ -6,6 +6,7 @@
|
||||
#include "mmr_can_includes.h"
|
||||
#include "mmr_can_types.h"
|
||||
#include "mmr_can_optimize.h"
|
||||
#include "mmr_can_binary_literals.h"
|
||||
|
||||
#ifndef MMR_CAN_RX_FIFO
|
||||
#define MMR_CAN_RX_FIFO CAN_RX_FIFO0
|
||||
@@ -23,15 +24,11 @@
|
||||
#define MMR_CAN_RX_INTERRUPT CAN_IT_RX_FIFO1_MSG_PENDING
|
||||
#endif
|
||||
|
||||
#ifndef MMR_CAN_ID
|
||||
#define MMR_CAN_ID 0x103
|
||||
#ifndef MMR_CAN_MAX_DATA_LENGTH
|
||||
#define MMR_CAN_MAX_DATA_LENGTH 8
|
||||
#endif
|
||||
|
||||
#ifndef MMR_CAN_BUFFER_LEN
|
||||
#define MMR_CAN_BUFFER_LEN 8
|
||||
#endif
|
||||
|
||||
typedef uint8_t CanRxBuffer[MMR_CAN_BUFFER_LEN];
|
||||
typedef uint8_t CanRxBuffer[MMR_CAN_MAX_DATA_LENGTH];
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -47,7 +44,10 @@ typedef struct {
|
||||
* The filter bank to use
|
||||
*
|
||||
* In systems with more than one CAN interface,
|
||||
* this must go from 0 to slaveBankStart.
|
||||
* this must go from 0 to slaveBankStart for the master CAN
|
||||
* and from slaveBankStart to 27 for the slave CAN
|
||||
*
|
||||
* Master CAN is usually CAN1, while slave CAN is CAN2
|
||||
*/
|
||||
CanFilterBank bank;
|
||||
|
||||
@@ -63,13 +63,8 @@ typedef struct {
|
||||
CanFilterMask idMask;
|
||||
} MmrCanFilterSettings;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
* The id of the CAN interface that will receive the packet.
|
||||
*
|
||||
* If you are using the CANbus in loopback mode, it can be the
|
||||
* id that the sender is using.
|
||||
*/
|
||||
CanId remoteId;
|
||||
CanMailbox *mailbox;
|
||||
uint8_t *data;
|
||||
@@ -77,13 +72,48 @@ typedef struct {
|
||||
} MmrCanPacket;
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* These values can be appended to the extended-id
|
||||
* 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
|
||||
*
|
||||
* Multi-frame messages have a higher priority over normal ones
|
||||
*/
|
||||
typedef enum {
|
||||
MMR_CAN_MESSAGE_TYPE_MULTI_FRAME = B_(0010),
|
||||
MMR_CAN_MESSAGE_TYPE_MULTI_FRAME_END = B_(0011),
|
||||
MMR_CAN_MESSAGE_TYPE_NORMAL = B_(1000),
|
||||
} MmrCanMessageType;
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Represents a CAN message
|
||||
*/
|
||||
typedef struct {
|
||||
CanId senderId;
|
||||
void *store;
|
||||
} MmrCanMessage;
|
||||
|
||||
|
||||
#define MMR_CAN_FilterConfigDefault(phcan) \
|
||||
MMR_CAN_FilterConfig(phcan, MMR_CAN_GetDefaultFilterSettings())
|
||||
|
||||
|
||||
HalStatus MMR_CAN_BasicSetupAndStart(CanHandle *hcan);
|
||||
HalStatus MMR_CAN_FilterConfig(CanHandle *hcan, MmrCanFilterSettings settings);
|
||||
CanFilterMask MMR_CAN_AlignStandardMask(CanFilterMask baseMask);
|
||||
MmrCanFilterSettings MMR_CAN_GetDefaultFilterSettings();
|
||||
|
||||
HalStatus MMR_CAN_Send(CanHandle *hcan, MmrCanPacket packet);
|
||||
HalStatus MMR_CAN_Receive(CanHandle *hcan, MmrCanMessage *result);
|
||||
|
||||
|
||||
bool MMR_CAN_IsMultiFrame(CanRxHeader *header);
|
||||
bool MMR_CAN_IsMultiFrameEnd(CanRxHeader *header);
|
||||
|
||||
#endif /* INC_MMR_CAN_H_ */
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef INC_MMR_CAN_BINARY_LITERALS_H_
|
||||
#define INC_MMR_CAN_BINARY_LITERALS_H_
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* These set of macros (B_, B8_, B16_, B32_) allow one
|
||||
* to convert bit literals to their hexadecimal representation
|
||||
*
|
||||
* They are useful when it is needed to convey exactly which bits
|
||||
* are being set for a particular register, message etc...
|
||||
*
|
||||
* @example
|
||||
* B_(1010) = 0xA
|
||||
* B8_(1111, 1111) = 0xFF
|
||||
*
|
||||
* -----------------------------------------------------------
|
||||
* Macros taken from https://stackoverflow.com/a/7577517 and
|
||||
* sligthly readapted
|
||||
*/
|
||||
|
||||
#define __B_0000 0
|
||||
#define __B_0001 1
|
||||
#define __B_0010 2
|
||||
#define __B_0011 3
|
||||
#define __B_0100 4
|
||||
#define __B_0101 5
|
||||
#define __B_0110 6
|
||||
#define __B_0111 7
|
||||
#define __B_1000 8
|
||||
#define __B_1001 9
|
||||
#define __B_1010 a
|
||||
#define __B_1011 b
|
||||
#define __B_1100 c
|
||||
#define __B_1101 d
|
||||
#define __B_1110 e
|
||||
#define __B_1111 f
|
||||
|
||||
#define __B2H(bits) __B_ ## bits
|
||||
#define _B2H(bits) __B2H(bits)
|
||||
#define __HEX(n) 0x ## n
|
||||
#define _HEX(n) __HEX(n)
|
||||
#define __CCAT(a,b) a ## b
|
||||
#define _CCAT(a,b) __CCAT(a,b)
|
||||
|
||||
#define B_(a) _HEX(_B2H(a))
|
||||
#define B8_(a, b) _HEX(_CCAT(_B2H(a), _B2H(b)))
|
||||
#define B16_(a, b, c, d) \
|
||||
_HEX(_CCAT( \
|
||||
_CCAT(_B2H(a), _B2H(b)), \
|
||||
_CCAT(_B2H(c), _B2H(d)) \
|
||||
))
|
||||
|
||||
#define B32_(a, b, c, d, e, f, g, h) \
|
||||
_HEX(_CCAT( \
|
||||
_CCAT( \
|
||||
_CCAT(_B2H(a), _B2H(b)), \
|
||||
_CCAT(_B2H(c),_B2H(d))), \
|
||||
_CCAT( \
|
||||
_CCAT(_B2H(e), _B2H(f)), \
|
||||
_CCAT(_B2H(g), _B2H(h)) \
|
||||
) \
|
||||
))
|
||||
|
||||
#endif /* INC_MMR_CAN_BINARY_LITERALS_H_ */
|
||||
@@ -2,21 +2,19 @@
|
||||
#define INC_MMR_CAN_EVENTS_H_
|
||||
|
||||
#include "mmr_can.h"
|
||||
#include "mmr_can_util.h"
|
||||
|
||||
typedef struct {
|
||||
CanId senderId;
|
||||
uint8_t *message;
|
||||
} MmrCanEvent;
|
||||
|
||||
typedef void (*MmrCanEventHandler)(MmrCanEvent *event);
|
||||
typedef void (*MmrCanEventHandler)(const MmrCanMessage *event);
|
||||
|
||||
typedef struct {
|
||||
const MmrCanEventHandler *handlers;
|
||||
const size_t count;
|
||||
} MmrCanEventList;
|
||||
|
||||
#define MMR_CAN_CreateEventList(handlers) \
|
||||
(const MmrCanEventList) { handlers, sizeofarray(handlers) }
|
||||
|
||||
void MMR_CAN_InitRxHandlers(const MmrCanEventList *rxEvents);
|
||||
HalStatus MMR_CAN_InitRxHandlers(CanHandle *hcan, const MmrCanEventList *rxEvents);
|
||||
|
||||
|
||||
#endif /* INC_MMR_CAN_EVENTS_H_ */
|
||||
|
||||
@@ -35,5 +35,6 @@ typedef HAL_StatusTypeDef HalStatus;
|
||||
typedef CAN_HandleTypeDef CanHandle;
|
||||
typedef CAN_RxHeaderTypeDef CanRxHeader;
|
||||
typedef CAN_TxHeaderTypeDef CanTxHeader;
|
||||
typedef CAN_FilterTypeDef CanFilter;
|
||||
|
||||
#endif /* INC_MMR_CAN_TYPES_H_ */
|
||||
|
||||
+8
-5
@@ -4,14 +4,17 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define arrayLength(array) \
|
||||
#define sizeofarray(array) \
|
||||
(sizeof(array) / sizeof(*(array)))
|
||||
|
||||
#define stringArrayLength(array) \
|
||||
stringBufferLength((array), sizeof(array))
|
||||
stringBufferLength((array), sizeofarray(array))
|
||||
|
||||
#define stringBufferLength(pbuffer, maxLen) \
|
||||
strnlen((const char*)(pbuffer), maxLen)
|
||||
|
||||
#define min(a, b) ((a) < (b) ? a : b);
|
||||
#define mask(value, bits) (value & bits)
|
||||
|
||||
size_t stringBufferLength(uint8_t *buffer, size_t maxLen) {
|
||||
return strnlen((const char*)buffer, maxLen);
|
||||
}
|
||||
|
||||
#endif /* INC_MMR_CAN_UTIL_H_ */
|
||||
|
||||
Reference in New Issue
Block a user