The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
mbed 2
This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.
TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/em_can.h
- Committer:
- AnnaBridge
- Date:
- 2019-02-20
- Revision:
- 172:65be27845400
- Parent:
- 171:3a7713b1edbc
File content as of revision 172:65be27845400:
/***************************************************************************//** * @file em_can.h * @brief Controller Area Network API * @version 5.3.3 ******************************************************************************* * # License * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b> ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no * obligation to support this Software. Silicon Labs is providing the * Software "AS IS", with no express or implied warranties of any kind, * including, but not limited to, any implied warranties of merchantability * or fitness for any particular purpose or warranties against infringement * of any proprietary rights of a third party. * * Silicon Labs will not be liable for any consequential, incidental, or * special damages, or any other relief, or for any claim by any third party, * arising from your use of this Software. * ******************************************************************************/ #ifndef EM_CAN_H #define EM_CAN_H #include "em_bus.h" #include "em_device.h" #include <stdbool.h> #if defined(CAN_COUNT) && (CAN_COUNT > 0) #ifdef __cplusplus extern "C" { #endif /***************************************************************************//** * @addtogroup emlib * @{ ******************************************************************************/ /***************************************************************************//** * @addtogroup CAN * @{ ******************************************************************************/ /******************************************************************************* ******************************* DEFINES *********************************** ******************************************************************************/ /******************************************************************************* ******************************** ENUMS ************************************ ******************************************************************************/ /** CAN Status codes */ typedef enum { /** No error occurred during last CAN bus event. */ canErrorNoError = CAN_STATUS_LEC_NONE, /** * More than 5 equal bits in a sequence have occurred in a part of a received * message where this is not allowed. */ canErrorStuff = CAN_STATUS_LEC_STUFF, /** A fixed format part of a received frame has the wrong format. */ canErrorForm = CAN_STATUS_LEC_FORM, /** The message this CAN Core transmitted was not acknowledged by another node. */ canErrorAck = CAN_STATUS_LEC_ACK, /** Wrong monitored bus value : dominant when the module wanted to send a recessive. */ canErrorBit1 = CAN_STATUS_LEC_BIT1, /** Wrong monitored bus value : recessive when the module intended to send a dominant. */ canErrorBit0 = CAN_STATUS_LEC_BIT0, /** CRC check sum incorrect. */ canErrorCrc = CAN_STATUS_LEC_CRC, /** Unused. No new error since the cpu wrote this value */ canErrorUnused = CAN_STATUS_LEC_UNUSED } CAN_ErrorCode_TypeDef; /** CAN peripheral mode */ typedef enum { /** CAN peripheral in Normal mode : ready to send and receive messages */ canModeNormal, /** CAN peripheral in Basic mode : no use of the RAM */ canModeBasic, /** * CAN peripheral in Loopback mode : input from the CAN bus is disregarded * and comes from TX instead */ canModeLoopBack, /** * CAN peripheral in SilentLoopback mode : input from the CAN bus is * disregarded and comes from TX instead ; no output on the CAN bus */ canModeSilentLoopBack, /** CAN peripheral in Silent mode : no output on the CAN bus. If required to * send a dominant bit, it's rerouted internally so that the CAN module * monitors it but the CAN bus stays recessive. */ canModeSilent } CAN_Mode_TypeDef; /******************************************************************************* ******************************* STRUCTS *********************************** ******************************************************************************/ /** CAN Message Object TypeDef structure. LSBs is used */ typedef struct { /** Message number of this Message Object, [1 - 32] */ uint8_t msgNum; /** Id extended if true, standard if false */ bool extended; /** * Id of the message, with 11 bits (standard) or 28 bits (extended). * LSBs are used for both of them */ uint32_t id; /** Data Length Code [0 - 8] */ uint8_t dlc; /** Pointer to the data, [0 - 8] bytes */ uint8_t data[8]; /** Mask for id filtering */ uint32_t mask; /** Enable the use of 'extended' value for filtering */ bool extendedMask; /** Enable the use of 'direction' value for filtering */ bool directionMask; } CAN_MessageObject_TypeDef; /** CAN initialization structure. */ typedef struct { /** true to set the CAN Device in normal mode after init */ bool enable; /** True to reset messages during initialization */ bool resetMessages; /** Default bitrate */ uint32_t bitrate; /** Default Propagation Time Segment */ uint8_t propagationTimeSegment; /** Default Phase Buffer Segment 1 */ uint8_t phaseBufferSegment1; /** Default Phase Buffer Segment 2 */ uint8_t phaseBufferSegment2; /** Default Synchronisation Jump Width */ uint8_t synchronisationJumpWidth; } CAN_Init_TypeDef; /** * Default initialization of CAN_Init_TypeDef. The total duration of a bit with * these default parameters is 10 tq (time quantum : tq = brp/fsys, brp being * the baudrate prescaler and being set according to the wanted bitrate, fsys * beeing the CAN Device frequency). */ #define CAN_INIT_DEFAULT \ { \ true, /** Set the CAN Device in normal mode after init */ \ true, /** Reset messages during initialization */ \ 100000, /** Set bitrate to 100 000 */ \ 1, /** Set the Propagation Time Segment to 1 */ \ 4, /** Set the Phase Buffer Segment 1 to 4 */ \ 4, /** Set the Phase Buffer Segment 2 to 4 */ \ 1 /** Set the Synchronization Jump Width to 1 */ \ } /******************************************************************************* ***************************** PROTOTYPES ********************************** ******************************************************************************/ void CAN_Init(CAN_TypeDef *can, const CAN_Init_TypeDef *init); uint32_t CAN_GetClockFrequency(CAN_TypeDef *can); bool CAN_MessageLost(CAN_TypeDef *can, uint8_t interface, uint8_t msgNum); void CAN_SetRoute(CAN_TypeDef *can, bool active, uint16_t pinRxLoc, uint16_t pinTxLoc); void CAN_SetBitTiming(CAN_TypeDef *can, uint32_t bitrate, uint16_t propagationTimeSegment, uint16_t phaseBufferSegment1, uint16_t phaseBufferSegment2, uint16_t synchronisationJumpWidth); void CAN_SetMode(CAN_TypeDef *can, CAN_Mode_TypeDef mode); void CAN_SetIdAndFilter(CAN_TypeDef *can, uint8_t interface, bool useMask, const CAN_MessageObject_TypeDef *message, bool wait); void CAN_ConfigureMessageObject(CAN_TypeDef *can, uint8_t interface, uint8_t msgNum, bool valid, bool tx, bool remoteTransfer, bool endOfBuffer, bool wait); void CAN_SendMessage(CAN_TypeDef *can, uint8_t interface, const CAN_MessageObject_TypeDef *message, bool wait); void CAN_ReadMessage(CAN_TypeDef *can, uint8_t interface, CAN_MessageObject_TypeDef *message); void CAN_AbortSendMessage(CAN_TypeDef *can, uint8_t interface, uint8_t msgNum, bool wait); void CAN_ResetMessages(CAN_TypeDef *can, uint8_t interface); void CAN_Reset(CAN_TypeDef *can); void CAN_WriteData(CAN_TypeDef *can, uint8_t interface, const CAN_MessageObject_TypeDef *message); void CAN_SendRequest(CAN_TypeDef *can, uint8_t interface, uint8_t msgNum, bool wait); /***************************************************************************//** * @brief * Enable the Host Controller to send messages. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] enable * true to enable CAN device, false to disable it. If the CAN device is * enabled, it goes in normal mode (the default working mode). ******************************************************************************/ __STATIC_INLINE void CAN_Enable(CAN_TypeDef *can, bool enable) { BUS_RegBitWrite(&can->CTRL, _CAN_CTRL_INIT_SHIFT, (enable ? 0 : 1)); } /***************************************************************************//** * @brief * Gives the communication capabilities state. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * true if the Host Controller can send messages, false otherwise. ******************************************************************************/ __STATIC_INLINE bool CAN_IsEnabled(CAN_TypeDef *can) { return (can->CTRL & _CAN_CTRL_INIT_MASK) == 0; } /***************************************************************************//** * @brief * Waiting function. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] interface * Indicate which Message Interface Register to use. * ******************************************************************************/ __STATIC_INLINE void CAN_ReadyWait(CAN_TypeDef *can, uint8_t interface) { while ((_CAN_MIR_CMDREQ_BUSY_MASK & can->MIR[interface].CMDREQ) != 0) { } } /***************************************************************************//** * @brief * Get the last error code and clear its register. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * return Last error code. ******************************************************************************/ __STATIC_INLINE CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(CAN_TypeDef *can) { CAN_ErrorCode_TypeDef errorCode = (CAN_ErrorCode_TypeDef) (can->STATUS & _CAN_STATUS_LEC_MASK); can->STATUS |= ~_CAN_STATUS_LEC_MASK; return errorCode; } /***************************************************************************//** * @brief * Indicates which messages objects have received new data. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * State of MESSAGEDATA register indicating which messages objects have received * new data. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_HasNewdata(CAN_TypeDef *can) { return can->MESSAGEDATA; } /***************************************************************************//** * @brief * Clear one or more pending CAN status interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * Pending CAN status interrupt source(s) to clear. ******************************************************************************/ __STATIC_INLINE void CAN_StatusIntClear(CAN_TypeDef *can, uint32_t flags) { can->IF1IFC = flags; } /***************************************************************************//** * @brief * Disable CAN status interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN status interrupt source(s) to disable. ******************************************************************************/ __STATIC_INLINE void CAN_StatusIntDisable(CAN_TypeDef *can, uint32_t flags) { can->IF1IEN &= ~flags; } /***************************************************************************//** * @brief * Enable CAN status interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN status interrupt source(s) to enable. ******************************************************************************/ __STATIC_INLINE void CAN_StatusIntEnable(CAN_TypeDef *can, uint32_t flags) { can->IF1IEN |= flags; } /***************************************************************************//** * @brief * Get pending CAN status interrupt flags. * * @note * The event bits are not cleared by the use of this function. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * CAN interrupt source(s) pending. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_StatusIntGet(CAN_TypeDef *can) { return can->IF1IF; } /***************************************************************************//** * @brief * Get pending and enabled CAN status interrupt flags. * * @note * The event bits are not cleared by the use of this function. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * CAN interrupt source(s) pending and enabled. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_StatusIntGetEnabled(CAN_TypeDef *can) { uint32_t ien; ien = can->IF1IEN; return can->IF1IF & ien; } /***************************************************************************//** * @brief * Set one or more CAN status interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN status interrupt source(s) to set to pending. ******************************************************************************/ __STATIC_INLINE void CAN_StatusIntSet(CAN_TypeDef *can, uint32_t flags) { can->IF1IFS = flags; } /***************************************************************************//** * @brief * Get CAN status. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * Value of CAN register STATUS. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_StatusGet(CAN_TypeDef *can) { return can->STATUS & ~_CAN_STATUS_LEC_MASK; } /***************************************************************************//** * @brief * Clear CAN status. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN status bits to clear. ******************************************************************************/ __STATIC_INLINE void CAN_StatusClear(CAN_TypeDef *can, uint32_t flags) { can->STATUS &= ~flags; } /***************************************************************************//** * @brief * Get the error count. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * Error count. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_GetErrorCount(CAN_TypeDef *can) { return can->ERRCNT; } /***************************************************************************//** * @brief * Clear one or more pending CAN message interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * Pending CAN message interrupt source(s) to clear. ******************************************************************************/ __STATIC_INLINE void CAN_MessageIntClear(CAN_TypeDef *can, uint32_t flags) { can->IF0IFC = flags; } /***************************************************************************//** * @brief * Disable CAN message interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN message interrupt source(s) to disable. ******************************************************************************/ __STATIC_INLINE void CAN_MessageIntDisable(CAN_TypeDef *can, uint32_t flags) { can->IF0IEN &= ~flags; } /***************************************************************************//** * @brief * Enable CAN message interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN message interrupt source(s) to enable. ******************************************************************************/ __STATIC_INLINE void CAN_MessageIntEnable(CAN_TypeDef *can, uint32_t flags) { can->IF0IEN |= flags; } /***************************************************************************//** * @brief * Get pending CAN message interrupt flags. * * @note * The event bits are not cleared by the use of this function. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * CAN message interrupt source(s) pending. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_MessageIntGet(CAN_TypeDef *can) { return can->IF0IF; } /***************************************************************************//** * @brief * Get CAN message interrupt flags that are pending and enabled. * * @note * The event bits are not cleared by the use of this function. * * @param[in] can * Pointer to CAN peripheral register block. * * @return * CAN message interrupt source(s) pending and enabled. ******************************************************************************/ __STATIC_INLINE uint32_t CAN_MessageIntGetEnabled(CAN_TypeDef *can) { uint32_t ien; ien = can->IF0IEN; return can->IF0IF & ien; } /***************************************************************************//** * @brief * Set one or more CAN message interrupts. * * @param[in] can * Pointer to CAN peripheral register block. * * @param[in] flags * CAN message interrupt source(s) to set to pending. ******************************************************************************/ __STATIC_INLINE void CAN_MessageIntSet(CAN_TypeDef *can, uint32_t flags) { can->IF0IFS = flags; } /** @} (end addtogroup CAN) */ /** @} (end addtogroup emlib) */ #ifdef __cplusplus } #endif #endif /* defined(CAN_COUNT) && (CAN_COUNT > 0) */ #endif /* EM_CAN_H */