Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /**************************************************************************//**
sahilmgandhi 18:6a4db94011d3 2 * @file can.c
sahilmgandhi 18:6a4db94011d3 3 * @version V2.00
sahilmgandhi 18:6a4db94011d3 4 * $Revision: 8 $
sahilmgandhi 18:6a4db94011d3 5 * $Date: 15/08/11 10:26a $
sahilmgandhi 18:6a4db94011d3 6 * @brief M451 series CAN driver source file
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * @note
sahilmgandhi 18:6a4db94011d3 9 * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
sahilmgandhi 18:6a4db94011d3 10 *****************************************************************************/
sahilmgandhi 18:6a4db94011d3 11 #include "M451Series.h"
sahilmgandhi 18:6a4db94011d3 12
sahilmgandhi 18:6a4db94011d3 13 /** @addtogroup Standard_Driver Standard Driver
sahilmgandhi 18:6a4db94011d3 14 @{
sahilmgandhi 18:6a4db94011d3 15 */
sahilmgandhi 18:6a4db94011d3 16
sahilmgandhi 18:6a4db94011d3 17 /** @addtogroup CAN_Driver CAN Driver
sahilmgandhi 18:6a4db94011d3 18 @{
sahilmgandhi 18:6a4db94011d3 19 */
sahilmgandhi 18:6a4db94011d3 20
sahilmgandhi 18:6a4db94011d3 21 /** @addtogroup CAN_EXPORTED_FUNCTIONS CAN Exported Functions
sahilmgandhi 18:6a4db94011d3 22 @{
sahilmgandhi 18:6a4db94011d3 23 */
sahilmgandhi 18:6a4db94011d3 24
sahilmgandhi 18:6a4db94011d3 25 /// @cond HIDDEN_SYMBOLS
sahilmgandhi 18:6a4db94011d3 26
sahilmgandhi 18:6a4db94011d3 27 #if defined(CAN1)
sahilmgandhi 18:6a4db94011d3 28 static uint8_t gu8LockCanIf[2][2] = {0}; // The chip has two CANs.
sahilmgandhi 18:6a4db94011d3 29 #elif defined(CAN0) || defined(CAN)
sahilmgandhi 18:6a4db94011d3 30 static uint8_t gu8LockCanIf[1][2] = {0}; // The chip only has one CAN.
sahilmgandhi 18:6a4db94011d3 31 #endif
sahilmgandhi 18:6a4db94011d3 32
sahilmgandhi 18:6a4db94011d3 33 #define RETRY_COUNTS (0x10000000)
sahilmgandhi 18:6a4db94011d3 34
sahilmgandhi 18:6a4db94011d3 35 //#define DEBUG_PRINTF printf
sahilmgandhi 18:6a4db94011d3 36 #define DEBUG_PRINTF(...)
sahilmgandhi 18:6a4db94011d3 37
sahilmgandhi 18:6a4db94011d3 38 /**
sahilmgandhi 18:6a4db94011d3 39 * @brief Check if any interface is available then lock it for usage.
sahilmgandhi 18:6a4db94011d3 40 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 41 * @retval 0 IF0 is free
sahilmgandhi 18:6a4db94011d3 42 * @retval 1 IF1 is free
sahilmgandhi 18:6a4db94011d3 43 * @retval 2 No IF is free
sahilmgandhi 18:6a4db94011d3 44 * @details Search the first free message interface, starting from 0. If a interface is
sahilmgandhi 18:6a4db94011d3 45 * available, set a flag to lock the interface.
sahilmgandhi 18:6a4db94011d3 46 */
sahilmgandhi 18:6a4db94011d3 47 static uint32_t LockIF(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 48 {
sahilmgandhi 18:6a4db94011d3 49 uint32_t u32CanNo;
sahilmgandhi 18:6a4db94011d3 50 uint32_t u32FreeIfNo;
sahilmgandhi 18:6a4db94011d3 51 uint32_t u32IntMask;
sahilmgandhi 18:6a4db94011d3 52
sahilmgandhi 18:6a4db94011d3 53 #if defined(CAN1)
sahilmgandhi 18:6a4db94011d3 54 u32CanNo = (tCAN == CAN1) ? 1 : 0;
sahilmgandhi 18:6a4db94011d3 55 #else // defined(CAN0) || defined(CAN)
sahilmgandhi 18:6a4db94011d3 56 u32CanNo = 0;
sahilmgandhi 18:6a4db94011d3 57 #endif
sahilmgandhi 18:6a4db94011d3 58
sahilmgandhi 18:6a4db94011d3 59 u32FreeIfNo = 2;
sahilmgandhi 18:6a4db94011d3 60
sahilmgandhi 18:6a4db94011d3 61 /* Disable CAN interrupt */
sahilmgandhi 18:6a4db94011d3 62 u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
sahilmgandhi 18:6a4db94011d3 63 tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
sahilmgandhi 18:6a4db94011d3 64
sahilmgandhi 18:6a4db94011d3 65 /* Check interface 1 is available or not */
sahilmgandhi 18:6a4db94011d3 66 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
sahilmgandhi 18:6a4db94011d3 67 {
sahilmgandhi 18:6a4db94011d3 68 if(gu8LockCanIf[u32CanNo][0] == FALSE)
sahilmgandhi 18:6a4db94011d3 69 {
sahilmgandhi 18:6a4db94011d3 70 gu8LockCanIf[u32CanNo][0] = TRUE;
sahilmgandhi 18:6a4db94011d3 71 u32FreeIfNo = 0;
sahilmgandhi 18:6a4db94011d3 72 }
sahilmgandhi 18:6a4db94011d3 73 }
sahilmgandhi 18:6a4db94011d3 74
sahilmgandhi 18:6a4db94011d3 75 /* Or check interface 2 is available or not */
sahilmgandhi 18:6a4db94011d3 76 if(u32FreeIfNo == 2 && (tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
sahilmgandhi 18:6a4db94011d3 77 {
sahilmgandhi 18:6a4db94011d3 78 if(gu8LockCanIf[u32CanNo][1] == FALSE)
sahilmgandhi 18:6a4db94011d3 79 {
sahilmgandhi 18:6a4db94011d3 80 gu8LockCanIf[u32CanNo][1] = TRUE;
sahilmgandhi 18:6a4db94011d3 81 u32FreeIfNo = 1;
sahilmgandhi 18:6a4db94011d3 82 }
sahilmgandhi 18:6a4db94011d3 83 }
sahilmgandhi 18:6a4db94011d3 84
sahilmgandhi 18:6a4db94011d3 85 /* Enable CAN interrupt */
sahilmgandhi 18:6a4db94011d3 86 tCAN->CON |= u32IntMask;
sahilmgandhi 18:6a4db94011d3 87
sahilmgandhi 18:6a4db94011d3 88 return u32FreeIfNo;
sahilmgandhi 18:6a4db94011d3 89 }
sahilmgandhi 18:6a4db94011d3 90
sahilmgandhi 18:6a4db94011d3 91 /**
sahilmgandhi 18:6a4db94011d3 92 * @brief Check if any interface is available in a time limitation then lock it for usage.
sahilmgandhi 18:6a4db94011d3 93 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 94 * @retval 0 IF0 is free
sahilmgandhi 18:6a4db94011d3 95 * @retval 1 IF1 is free
sahilmgandhi 18:6a4db94011d3 96 * @retval 2 No IF is free
sahilmgandhi 18:6a4db94011d3 97 * @details Search the first free message interface, starting from 0. If no interface is
sahilmgandhi 18:6a4db94011d3 98 * it will try again until time out. If a interface is available, set a flag to
sahilmgandhi 18:6a4db94011d3 99 * lock the interface.
sahilmgandhi 18:6a4db94011d3 100 */
sahilmgandhi 18:6a4db94011d3 101 static uint32_t LockIF_TL(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 102 {
sahilmgandhi 18:6a4db94011d3 103 uint32_t u32Count;
sahilmgandhi 18:6a4db94011d3 104 uint32_t u32FreeIfNo;
sahilmgandhi 18:6a4db94011d3 105
sahilmgandhi 18:6a4db94011d3 106 for(u32Count = 0; u32Count < RETRY_COUNTS; u32Count++)
sahilmgandhi 18:6a4db94011d3 107 {
sahilmgandhi 18:6a4db94011d3 108 if((u32FreeIfNo = LockIF(tCAN)) != 2)
sahilmgandhi 18:6a4db94011d3 109 return u32FreeIfNo;
sahilmgandhi 18:6a4db94011d3 110 }
sahilmgandhi 18:6a4db94011d3 111
sahilmgandhi 18:6a4db94011d3 112 return u32FreeIfNo;
sahilmgandhi 18:6a4db94011d3 113 }
sahilmgandhi 18:6a4db94011d3 114
sahilmgandhi 18:6a4db94011d3 115 /**
sahilmgandhi 18:6a4db94011d3 116 * @brief Release locked interface.
sahilmgandhi 18:6a4db94011d3 117 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 118 * @param[in] u32Info The interface number, 0 or 1.
sahilmgandhi 18:6a4db94011d3 119 * @return none
sahilmgandhi 18:6a4db94011d3 120 * @details Release the locked interface.
sahilmgandhi 18:6a4db94011d3 121 */
sahilmgandhi 18:6a4db94011d3 122 static void ReleaseIF(CAN_T *tCAN, uint32_t u32IfNo)
sahilmgandhi 18:6a4db94011d3 123 {
sahilmgandhi 18:6a4db94011d3 124 uint32_t u32IntMask;
sahilmgandhi 18:6a4db94011d3 125 uint32_t u32CanNo;
sahilmgandhi 18:6a4db94011d3 126
sahilmgandhi 18:6a4db94011d3 127 if(u32IfNo >= 2)
sahilmgandhi 18:6a4db94011d3 128 return;
sahilmgandhi 18:6a4db94011d3 129
sahilmgandhi 18:6a4db94011d3 130 #if defined(CAN1)
sahilmgandhi 18:6a4db94011d3 131 u32CanNo = (tCAN == CAN1) ? 1 : 0;
sahilmgandhi 18:6a4db94011d3 132 #else // defined(CAN0) || defined(CAN)
sahilmgandhi 18:6a4db94011d3 133 u32CanNo = 0;
sahilmgandhi 18:6a4db94011d3 134 #endif
sahilmgandhi 18:6a4db94011d3 135
sahilmgandhi 18:6a4db94011d3 136 /* Disable CAN interrupt */
sahilmgandhi 18:6a4db94011d3 137 u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
sahilmgandhi 18:6a4db94011d3 138 tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
sahilmgandhi 18:6a4db94011d3 139
sahilmgandhi 18:6a4db94011d3 140 gu8LockCanIf[u32CanNo][u32IfNo] = FALSE;
sahilmgandhi 18:6a4db94011d3 141
sahilmgandhi 18:6a4db94011d3 142 /* Enable CAN interrupt */
sahilmgandhi 18:6a4db94011d3 143 tCAN->CON |= u32IntMask;
sahilmgandhi 18:6a4db94011d3 144 }
sahilmgandhi 18:6a4db94011d3 145
sahilmgandhi 18:6a4db94011d3 146 /**
sahilmgandhi 18:6a4db94011d3 147 * @brief Enter initialization mode
sahilmgandhi 18:6a4db94011d3 148 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 149 * @param[in] Following values can be used.
sahilmgandhi 18:6a4db94011d3 150 * \ref CAN_CON_DAR_Msk Disable automatic retransmission.
sahilmgandhi 18:6a4db94011d3 151 * \ref CAN_CON_EIE_Msk Enable error interrupt.
sahilmgandhi 18:6a4db94011d3 152 * \ref CAN_CON_SIE_Msk Enable status interrupt.
sahilmgandhi 18:6a4db94011d3 153 * \ref CAN_CON_IE_Msk CAN interrupt.
sahilmgandhi 18:6a4db94011d3 154 * @return None
sahilmgandhi 18:6a4db94011d3 155 * @details This function is used to set CAN to enter initialization mode and enable access bit timing
sahilmgandhi 18:6a4db94011d3 156 * register. After bit timing configuration ready, user must call CAN_LeaveInitMode()
sahilmgandhi 18:6a4db94011d3 157 * to leave initialization mode and lock bit timing register to let new configuration
sahilmgandhi 18:6a4db94011d3 158 * take effect.
sahilmgandhi 18:6a4db94011d3 159 */
sahilmgandhi 18:6a4db94011d3 160 void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask)
sahilmgandhi 18:6a4db94011d3 161 {
sahilmgandhi 18:6a4db94011d3 162 tCAN->CON = u8Mask | (CAN_CON_INIT_Msk | CAN_CON_CCE_Msk);
sahilmgandhi 18:6a4db94011d3 163 }
sahilmgandhi 18:6a4db94011d3 164
sahilmgandhi 18:6a4db94011d3 165
sahilmgandhi 18:6a4db94011d3 166 /**
sahilmgandhi 18:6a4db94011d3 167 * @brief Leave initialization mode
sahilmgandhi 18:6a4db94011d3 168 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 169 * @return None
sahilmgandhi 18:6a4db94011d3 170 * @details This function is used to set CAN to leave initialization mode to let
sahilmgandhi 18:6a4db94011d3 171 * bit timing configuration take effect after configuration ready.
sahilmgandhi 18:6a4db94011d3 172 */
sahilmgandhi 18:6a4db94011d3 173 void CAN_LeaveInitMode(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 174 {
sahilmgandhi 18:6a4db94011d3 175 tCAN->CON &= (~(CAN_CON_INIT_Msk | CAN_CON_CCE_Msk));
sahilmgandhi 18:6a4db94011d3 176 while(tCAN->CON & CAN_CON_INIT_Msk); /* Check INIT bit is released */
sahilmgandhi 18:6a4db94011d3 177 }
sahilmgandhi 18:6a4db94011d3 178
sahilmgandhi 18:6a4db94011d3 179 /**
sahilmgandhi 18:6a4db94011d3 180 * @brief Wait message into message buffer in basic mode.
sahilmgandhi 18:6a4db94011d3 181 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 182 * @return None
sahilmgandhi 18:6a4db94011d3 183 * @details This function is used to wait message into message buffer in basic mode. Please notice the
sahilmgandhi 18:6a4db94011d3 184 * function is polling NEWDAT bit of MCON register by while loop and it is used in basic mode.
sahilmgandhi 18:6a4db94011d3 185 */
sahilmgandhi 18:6a4db94011d3 186 void CAN_WaitMsg(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 187 {
sahilmgandhi 18:6a4db94011d3 188 tCAN->STATUS = 0x0; /* clr status */
sahilmgandhi 18:6a4db94011d3 189
sahilmgandhi 18:6a4db94011d3 190 while(1)
sahilmgandhi 18:6a4db94011d3 191 {
sahilmgandhi 18:6a4db94011d3 192 if(tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) /* check new data */
sahilmgandhi 18:6a4db94011d3 193 {
sahilmgandhi 18:6a4db94011d3 194 DEBUG_PRINTF("New Data IN\n");
sahilmgandhi 18:6a4db94011d3 195 break;
sahilmgandhi 18:6a4db94011d3 196 }
sahilmgandhi 18:6a4db94011d3 197
sahilmgandhi 18:6a4db94011d3 198 if(tCAN->STATUS & CAN_STATUS_RXOK_Msk)
sahilmgandhi 18:6a4db94011d3 199 {
sahilmgandhi 18:6a4db94011d3 200 DEBUG_PRINTF("Rx OK\n");
sahilmgandhi 18:6a4db94011d3 201 }
sahilmgandhi 18:6a4db94011d3 202 if(tCAN->STATUS & CAN_STATUS_LEC_Msk)
sahilmgandhi 18:6a4db94011d3 203 {
sahilmgandhi 18:6a4db94011d3 204 DEBUG_PRINTF("Error\n");
sahilmgandhi 18:6a4db94011d3 205 }
sahilmgandhi 18:6a4db94011d3 206 }
sahilmgandhi 18:6a4db94011d3 207 }
sahilmgandhi 18:6a4db94011d3 208
sahilmgandhi 18:6a4db94011d3 209 /**
sahilmgandhi 18:6a4db94011d3 210 * @brief Get current bit rate
sahilmgandhi 18:6a4db94011d3 211 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 212 * @return Current Bit-Rate (kilo bit per second)
sahilmgandhi 18:6a4db94011d3 213 * @details Return current CAN bit rate according to the user bit-timing parameter settings
sahilmgandhi 18:6a4db94011d3 214 */
sahilmgandhi 18:6a4db94011d3 215 uint32_t CAN_GetCANBitRate(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 216 {
sahilmgandhi 18:6a4db94011d3 217 uint8_t u8Tseg1, u8Tseg2;
sahilmgandhi 18:6a4db94011d3 218 uint32_t u32Bpr;
sahilmgandhi 18:6a4db94011d3 219
sahilmgandhi 18:6a4db94011d3 220 u8Tseg1 = (tCAN->BTIME & CAN_BTIME_TSEG1_Msk) >> CAN_BTIME_TSEG1_Pos;
sahilmgandhi 18:6a4db94011d3 221 u8Tseg2 = (tCAN->BTIME & CAN_BTIME_TSEG2_Msk) >> CAN_BTIME_TSEG2_Pos;
sahilmgandhi 18:6a4db94011d3 222 u32Bpr = (tCAN->BTIME & CAN_BTIME_BRP_Msk) | (tCAN->BRPE << 6);
sahilmgandhi 18:6a4db94011d3 223
sahilmgandhi 18:6a4db94011d3 224 return (SystemCoreClock / (u32Bpr + 1) / (u8Tseg1 + u8Tseg2 + 3));
sahilmgandhi 18:6a4db94011d3 225 }
sahilmgandhi 18:6a4db94011d3 226
sahilmgandhi 18:6a4db94011d3 227 /**
sahilmgandhi 18:6a4db94011d3 228 * @brief Switch the CAN into test mode.
sahilmgandhi 18:6a4db94011d3 229 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 230 * @param[in] u8TestMask Specifies the configuration in test modes
sahilmgandhi 18:6a4db94011d3 231 * \ref CAN_TEST_BASIC_Msk Enable basic mode of test mode
sahilmgandhi 18:6a4db94011d3 232 * \ref CAN_TEST_SILENT_Msk Enable silent mode of test mode
sahilmgandhi 18:6a4db94011d3 233 * \ref CAN_TEST_LBACK_Msk Enable Loop Back Mode of test mode
sahilmgandhi 18:6a4db94011d3 234 * \ref CAN_TEST_TX0_Msk / \ref CAN_TEST_TX1_Msk Control CAN_TX pin bit field
sahilmgandhi 18:6a4db94011d3 235 * @return None
sahilmgandhi 18:6a4db94011d3 236 * @details Switch the CAN into test mode. There are four test mode (BASIC/SILENT/LOOPBACK/
sahilmgandhi 18:6a4db94011d3 237 * LOOPBACK combined SILENT/CONTROL_TX_PIN)could be selected. After setting test mode,user
sahilmgandhi 18:6a4db94011d3 238 * must call CAN_LeaveInitMode() to let the setting take effect.
sahilmgandhi 18:6a4db94011d3 239 */
sahilmgandhi 18:6a4db94011d3 240 void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask)
sahilmgandhi 18:6a4db94011d3 241 {
sahilmgandhi 18:6a4db94011d3 242 tCAN->CON |= CAN_CON_TEST_Msk;
sahilmgandhi 18:6a4db94011d3 243 tCAN->TEST = u8TestMask;
sahilmgandhi 18:6a4db94011d3 244 }
sahilmgandhi 18:6a4db94011d3 245
sahilmgandhi 18:6a4db94011d3 246
sahilmgandhi 18:6a4db94011d3 247 /**
sahilmgandhi 18:6a4db94011d3 248 * @brief Leave the test mode
sahilmgandhi 18:6a4db94011d3 249 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 250 * @return None
sahilmgandhi 18:6a4db94011d3 251 * @details This function is used to Leave the test mode (switch into normal mode).
sahilmgandhi 18:6a4db94011d3 252 */
sahilmgandhi 18:6a4db94011d3 253 void CAN_LeaveTestMode(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 254 {
sahilmgandhi 18:6a4db94011d3 255 tCAN->CON |= CAN_CON_TEST_Msk;
sahilmgandhi 18:6a4db94011d3 256 tCAN->TEST &= ~(CAN_TEST_LBACK_Msk | CAN_TEST_SILENT_Msk | CAN_TEST_BASIC_Msk);
sahilmgandhi 18:6a4db94011d3 257 tCAN->CON &= (~CAN_CON_TEST_Msk);
sahilmgandhi 18:6a4db94011d3 258 }
sahilmgandhi 18:6a4db94011d3 259
sahilmgandhi 18:6a4db94011d3 260 /**
sahilmgandhi 18:6a4db94011d3 261 * @brief Get the waiting status of a received message.
sahilmgandhi 18:6a4db94011d3 262 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 263 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 264 * @retval non-zero The corresponding message object has a new data bit is set.
sahilmgandhi 18:6a4db94011d3 265 * @retval 0 No message object has new data.
sahilmgandhi 18:6a4db94011d3 266 * @details This function is used to get the waiting status of a received message.
sahilmgandhi 18:6a4db94011d3 267 */
sahilmgandhi 18:6a4db94011d3 268 uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj)
sahilmgandhi 18:6a4db94011d3 269 {
sahilmgandhi 18:6a4db94011d3 270 return (u8MsgObj < 16 ? tCAN->NDAT1 & (1 << u8MsgObj) : tCAN->NDAT2 & (1 << (u8MsgObj - 16)));
sahilmgandhi 18:6a4db94011d3 271 }
sahilmgandhi 18:6a4db94011d3 272
sahilmgandhi 18:6a4db94011d3 273
sahilmgandhi 18:6a4db94011d3 274 /**
sahilmgandhi 18:6a4db94011d3 275 * @brief Send CAN message in BASIC mode of test mode
sahilmgandhi 18:6a4db94011d3 276 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 277 * @param[in] pCanMsg Pointer to the message structure containing data to transmit.
sahilmgandhi 18:6a4db94011d3 278 * @return TRUE: Transmission OK
sahilmgandhi 18:6a4db94011d3 279 * FALSE: Check busy flag of interface 0 is timeout
sahilmgandhi 18:6a4db94011d3 280 * @details The function is used to send CAN message in BASIC mode of test mode. Before call the API,
sahilmgandhi 18:6a4db94011d3 281 * the user should be call CAN_EnterTestMode(CAN_TEST_BASIC) and let CAN controller enter
sahilmgandhi 18:6a4db94011d3 282 * basic mode of test mode. Please notice IF1 Registers used as Tx Buffer in basic mode.
sahilmgandhi 18:6a4db94011d3 283 */
sahilmgandhi 18:6a4db94011d3 284 int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 285 {
sahilmgandhi 18:6a4db94011d3 286 uint32_t i = 0;
sahilmgandhi 18:6a4db94011d3 287 while(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk);
sahilmgandhi 18:6a4db94011d3 288
sahilmgandhi 18:6a4db94011d3 289 tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk);
sahilmgandhi 18:6a4db94011d3 290
sahilmgandhi 18:6a4db94011d3 291 if(pCanMsg->IdType == CAN_STD_ID)
sahilmgandhi 18:6a4db94011d3 292 {
sahilmgandhi 18:6a4db94011d3 293 /* standard ID*/
sahilmgandhi 18:6a4db94011d3 294 tCAN->IF[0].ARB1 = 0;
sahilmgandhi 18:6a4db94011d3 295 tCAN->IF[0].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) ;
sahilmgandhi 18:6a4db94011d3 296 }
sahilmgandhi 18:6a4db94011d3 297 else
sahilmgandhi 18:6a4db94011d3 298 {
sahilmgandhi 18:6a4db94011d3 299 /* extended ID*/
sahilmgandhi 18:6a4db94011d3 300 tCAN->IF[0].ARB1 = (pCanMsg->Id) & 0xFFFF;
sahilmgandhi 18:6a4db94011d3 301 tCAN->IF[0].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 | CAN_IF_ARB2_XTD_Msk;
sahilmgandhi 18:6a4db94011d3 302
sahilmgandhi 18:6a4db94011d3 303 }
sahilmgandhi 18:6a4db94011d3 304
sahilmgandhi 18:6a4db94011d3 305 if(pCanMsg->FrameType)
sahilmgandhi 18:6a4db94011d3 306 tCAN->IF[0].ARB2 |= CAN_IF_ARB2_DIR_Msk;
sahilmgandhi 18:6a4db94011d3 307 else
sahilmgandhi 18:6a4db94011d3 308 tCAN->IF[0].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
sahilmgandhi 18:6a4db94011d3 309
sahilmgandhi 18:6a4db94011d3 310 tCAN->IF[0].MCON = (tCAN->IF[0].MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->DLC;
sahilmgandhi 18:6a4db94011d3 311 tCAN->IF[0].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0];
sahilmgandhi 18:6a4db94011d3 312 tCAN->IF[0].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2];
sahilmgandhi 18:6a4db94011d3 313 tCAN->IF[0].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4];
sahilmgandhi 18:6a4db94011d3 314 tCAN->IF[0].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6];
sahilmgandhi 18:6a4db94011d3 315
sahilmgandhi 18:6a4db94011d3 316 /* request transmission*/
sahilmgandhi 18:6a4db94011d3 317 tCAN->IF[0].CREQ &= (~CAN_IF_CREQ_BUSY_Msk);
sahilmgandhi 18:6a4db94011d3 318 if(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk)
sahilmgandhi 18:6a4db94011d3 319 {
sahilmgandhi 18:6a4db94011d3 320 DEBUG_PRINTF("Cannot clear busy for sending ...\n");
sahilmgandhi 18:6a4db94011d3 321 return FALSE;
sahilmgandhi 18:6a4db94011d3 322 }
sahilmgandhi 18:6a4db94011d3 323
sahilmgandhi 18:6a4db94011d3 324 tCAN->IF[0].CREQ |= CAN_IF_CREQ_BUSY_Msk; // sending
sahilmgandhi 18:6a4db94011d3 325
sahilmgandhi 18:6a4db94011d3 326 for(i = 0; i < 0xFFFFF; i++)
sahilmgandhi 18:6a4db94011d3 327 {
sahilmgandhi 18:6a4db94011d3 328 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
sahilmgandhi 18:6a4db94011d3 329 break;
sahilmgandhi 18:6a4db94011d3 330 }
sahilmgandhi 18:6a4db94011d3 331
sahilmgandhi 18:6a4db94011d3 332 if(i >= 0xFFFFF)
sahilmgandhi 18:6a4db94011d3 333 {
sahilmgandhi 18:6a4db94011d3 334 DEBUG_PRINTF("Cannot send out...\n");
sahilmgandhi 18:6a4db94011d3 335 return FALSE;
sahilmgandhi 18:6a4db94011d3 336 }
sahilmgandhi 18:6a4db94011d3 337
sahilmgandhi 18:6a4db94011d3 338 return TRUE;
sahilmgandhi 18:6a4db94011d3 339 }
sahilmgandhi 18:6a4db94011d3 340
sahilmgandhi 18:6a4db94011d3 341 /**
sahilmgandhi 18:6a4db94011d3 342 * @brief Get a message information in BASIC mode.
sahilmgandhi 18:6a4db94011d3 343 *
sahilmgandhi 18:6a4db94011d3 344 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 345 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
sahilmgandhi 18:6a4db94011d3 346 *
sahilmgandhi 18:6a4db94011d3 347 * @return FALSE No any message received.
sahilmgandhi 18:6a4db94011d3 348 * TRUE Receive a message success.
sahilmgandhi 18:6a4db94011d3 349 *
sahilmgandhi 18:6a4db94011d3 350 */
sahilmgandhi 18:6a4db94011d3 351 int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 352 {
sahilmgandhi 18:6a4db94011d3 353
sahilmgandhi 18:6a4db94011d3 354 if((tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) == 0) /* In basic mode, receive data always save in IF2 */
sahilmgandhi 18:6a4db94011d3 355 {
sahilmgandhi 18:6a4db94011d3 356 return FALSE;
sahilmgandhi 18:6a4db94011d3 357 }
sahilmgandhi 18:6a4db94011d3 358
sahilmgandhi 18:6a4db94011d3 359 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
sahilmgandhi 18:6a4db94011d3 360
sahilmgandhi 18:6a4db94011d3 361 tCAN->IF[1].CMASK = CAN_IF_CMASK_ARB_Msk
sahilmgandhi 18:6a4db94011d3 362 | CAN_IF_CMASK_CONTROL_Msk
sahilmgandhi 18:6a4db94011d3 363 | CAN_IF_CMASK_DATAA_Msk
sahilmgandhi 18:6a4db94011d3 364 | CAN_IF_CMASK_DATAB_Msk;
sahilmgandhi 18:6a4db94011d3 365
sahilmgandhi 18:6a4db94011d3 366 if((tCAN->IF[1].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
sahilmgandhi 18:6a4db94011d3 367 {
sahilmgandhi 18:6a4db94011d3 368 /* standard ID*/
sahilmgandhi 18:6a4db94011d3 369 pCanMsg->IdType = CAN_STD_ID;
sahilmgandhi 18:6a4db94011d3 370 pCanMsg->Id = (tCAN->IF[1].ARB2 >> 2) & 0x07FF;
sahilmgandhi 18:6a4db94011d3 371
sahilmgandhi 18:6a4db94011d3 372 }
sahilmgandhi 18:6a4db94011d3 373 else
sahilmgandhi 18:6a4db94011d3 374 {
sahilmgandhi 18:6a4db94011d3 375 /* extended ID*/
sahilmgandhi 18:6a4db94011d3 376 pCanMsg->IdType = CAN_EXT_ID;
sahilmgandhi 18:6a4db94011d3 377 pCanMsg->Id = (tCAN->IF[1].ARB2 & 0x1FFF) << 16;
sahilmgandhi 18:6a4db94011d3 378 pCanMsg->Id |= (uint32_t)tCAN->IF[1].ARB1;
sahilmgandhi 18:6a4db94011d3 379 }
sahilmgandhi 18:6a4db94011d3 380
sahilmgandhi 18:6a4db94011d3 381 pCanMsg->FrameType = !((tCAN->IF[1].ARB2 & CAN_IF_ARB2_DIR_Msk) >> CAN_IF_ARB2_DIR_Pos);
sahilmgandhi 18:6a4db94011d3 382
sahilmgandhi 18:6a4db94011d3 383 pCanMsg->DLC = tCAN->IF[1].MCON & CAN_IF_MCON_DLC_Msk;
sahilmgandhi 18:6a4db94011d3 384 pCanMsg->Data[0] = tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
sahilmgandhi 18:6a4db94011d3 385 pCanMsg->Data[1] = (tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
sahilmgandhi 18:6a4db94011d3 386 pCanMsg->Data[2] = tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
sahilmgandhi 18:6a4db94011d3 387 pCanMsg->Data[3] = (tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
sahilmgandhi 18:6a4db94011d3 388 pCanMsg->Data[4] = tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
sahilmgandhi 18:6a4db94011d3 389 pCanMsg->Data[5] = (tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
sahilmgandhi 18:6a4db94011d3 390 pCanMsg->Data[6] = tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
sahilmgandhi 18:6a4db94011d3 391 pCanMsg->Data[7] = (tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
sahilmgandhi 18:6a4db94011d3 392
sahilmgandhi 18:6a4db94011d3 393 return TRUE;
sahilmgandhi 18:6a4db94011d3 394 }
sahilmgandhi 18:6a4db94011d3 395
sahilmgandhi 18:6a4db94011d3 396 /**
sahilmgandhi 18:6a4db94011d3 397 * @brief Set Rx message object, include ID mask.
sahilmgandhi 18:6a4db94011d3 398 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 399 * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted
sahilmgandhi 18:6a4db94011d3 400 * This parameter can be one of the following values:
sahilmgandhi 18:6a4db94011d3 401 * \ref CAN_STD_ID (standard ID, 11-bit)
sahilmgandhi 18:6a4db94011d3 402 * \ref CAN_EXT_ID (extended ID, 29-bit)
sahilmgandhi 18:6a4db94011d3 403 * @param[in] u32id Specifies the identifier used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 404 * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator.
sahilmgandhi 18:6a4db94011d3 405 * This parameter can be one of the following values:
sahilmgandhi 18:6a4db94011d3 406 * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO.
sahilmgandhi 18:6a4db94011d3 407 * FALSE: for a FIFO receive object that is not the last one.
sahilmgandhi 18:6a4db94011d3 408 * @retval TRUE SUCCESS
sahilmgandhi 18:6a4db94011d3 409 * @retval FALSE No useful interface
sahilmgandhi 18:6a4db94011d3 410 * @details The function is used to configure a receive message object.
sahilmgandhi 18:6a4db94011d3 411 */
sahilmgandhi 18:6a4db94011d3 412 int32_t CAN_SetRxMsgObjAndMsk(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast)
sahilmgandhi 18:6a4db94011d3 413 {
sahilmgandhi 18:6a4db94011d3 414 uint8_t u8MsgIfNum;
sahilmgandhi 18:6a4db94011d3 415
sahilmgandhi 18:6a4db94011d3 416 /* Get and lock a free interface */
sahilmgandhi 18:6a4db94011d3 417 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 418 return FALSE;
sahilmgandhi 18:6a4db94011d3 419
sahilmgandhi 18:6a4db94011d3 420 /* Command Setting */
sahilmgandhi 18:6a4db94011d3 421 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
sahilmgandhi 18:6a4db94011d3 422 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
sahilmgandhi 18:6a4db94011d3 423
sahilmgandhi 18:6a4db94011d3 424 if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */
sahilmgandhi 18:6a4db94011d3 425 {
sahilmgandhi 18:6a4db94011d3 426 tCAN->IF[u8MsgIfNum].ARB1 = 0;
sahilmgandhi 18:6a4db94011d3 427 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2;
sahilmgandhi 18:6a4db94011d3 428 }
sahilmgandhi 18:6a4db94011d3 429 else
sahilmgandhi 18:6a4db94011d3 430 {
sahilmgandhi 18:6a4db94011d3 431 tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF;
sahilmgandhi 18:6a4db94011d3 432 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16;
sahilmgandhi 18:6a4db94011d3 433 }
sahilmgandhi 18:6a4db94011d3 434
sahilmgandhi 18:6a4db94011d3 435 tCAN->IF[u8MsgIfNum].MASK1 = (u32idmask & 0xFFFF);
sahilmgandhi 18:6a4db94011d3 436 tCAN->IF[u8MsgIfNum].MASK2 = (u32idmask >> 16) & 0xFFFF;
sahilmgandhi 18:6a4db94011d3 437
sahilmgandhi 18:6a4db94011d3 438 //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
sahilmgandhi 18:6a4db94011d3 439 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
sahilmgandhi 18:6a4db94011d3 440 if(u8singleOrFifoLast)
sahilmgandhi 18:6a4db94011d3 441 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk;
sahilmgandhi 18:6a4db94011d3 442 else
sahilmgandhi 18:6a4db94011d3 443 tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk);
sahilmgandhi 18:6a4db94011d3 444
sahilmgandhi 18:6a4db94011d3 445 tCAN->IF[u8MsgIfNum].DAT_A1 = 0;
sahilmgandhi 18:6a4db94011d3 446 tCAN->IF[u8MsgIfNum].DAT_A2 = 0;
sahilmgandhi 18:6a4db94011d3 447 tCAN->IF[u8MsgIfNum].DAT_B1 = 0;
sahilmgandhi 18:6a4db94011d3 448 tCAN->IF[u8MsgIfNum].DAT_B2 = 0;
sahilmgandhi 18:6a4db94011d3 449
sahilmgandhi 18:6a4db94011d3 450 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
sahilmgandhi 18:6a4db94011d3 451 ReleaseIF(tCAN, u8MsgIfNum);
sahilmgandhi 18:6a4db94011d3 452
sahilmgandhi 18:6a4db94011d3 453 return TRUE;
sahilmgandhi 18:6a4db94011d3 454 }
sahilmgandhi 18:6a4db94011d3 455
sahilmgandhi 18:6a4db94011d3 456 /**
sahilmgandhi 18:6a4db94011d3 457 * @brief Set Rx message object
sahilmgandhi 18:6a4db94011d3 458 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 459 * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted
sahilmgandhi 18:6a4db94011d3 460 * This parameter can be one of the following values:
sahilmgandhi 18:6a4db94011d3 461 * \ref CAN_STD_ID (standard ID, 11-bit)
sahilmgandhi 18:6a4db94011d3 462 * \ref CAN_EXT_ID (extended ID, 29-bit)
sahilmgandhi 18:6a4db94011d3 463 * @param[in] u32id Specifies the identifier used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 464 * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator.
sahilmgandhi 18:6a4db94011d3 465 * This parameter can be one of the following values:
sahilmgandhi 18:6a4db94011d3 466 * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO.
sahilmgandhi 18:6a4db94011d3 467 * FALSE: for a FIFO receive object that is not the last one.
sahilmgandhi 18:6a4db94011d3 468 * @retval TRUE SUCCESS
sahilmgandhi 18:6a4db94011d3 469 * @retval FALSE No useful interface
sahilmgandhi 18:6a4db94011d3 470 * @details The function is used to configure a receive message object.
sahilmgandhi 18:6a4db94011d3 471 */
sahilmgandhi 18:6a4db94011d3 472 int32_t CAN_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
sahilmgandhi 18:6a4db94011d3 473 {
sahilmgandhi 18:6a4db94011d3 474 uint8_t u8MsgIfNum;
sahilmgandhi 18:6a4db94011d3 475
sahilmgandhi 18:6a4db94011d3 476 /* Get and lock a free interface */
sahilmgandhi 18:6a4db94011d3 477 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 478 return FALSE;
sahilmgandhi 18:6a4db94011d3 479
sahilmgandhi 18:6a4db94011d3 480 /* Command Setting */
sahilmgandhi 18:6a4db94011d3 481 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
sahilmgandhi 18:6a4db94011d3 482 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
sahilmgandhi 18:6a4db94011d3 483
sahilmgandhi 18:6a4db94011d3 484 if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */
sahilmgandhi 18:6a4db94011d3 485 {
sahilmgandhi 18:6a4db94011d3 486 tCAN->IF[u8MsgIfNum].ARB1 = 0;
sahilmgandhi 18:6a4db94011d3 487 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2;
sahilmgandhi 18:6a4db94011d3 488 }
sahilmgandhi 18:6a4db94011d3 489 else
sahilmgandhi 18:6a4db94011d3 490 {
sahilmgandhi 18:6a4db94011d3 491 tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF;
sahilmgandhi 18:6a4db94011d3 492 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16;
sahilmgandhi 18:6a4db94011d3 493 }
sahilmgandhi 18:6a4db94011d3 494
sahilmgandhi 18:6a4db94011d3 495 //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
sahilmgandhi 18:6a4db94011d3 496 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
sahilmgandhi 18:6a4db94011d3 497 if(u8singleOrFifoLast)
sahilmgandhi 18:6a4db94011d3 498 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk;
sahilmgandhi 18:6a4db94011d3 499 else
sahilmgandhi 18:6a4db94011d3 500 tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk);
sahilmgandhi 18:6a4db94011d3 501
sahilmgandhi 18:6a4db94011d3 502 tCAN->IF[u8MsgIfNum].DAT_A1 = 0;
sahilmgandhi 18:6a4db94011d3 503 tCAN->IF[u8MsgIfNum].DAT_A2 = 0;
sahilmgandhi 18:6a4db94011d3 504 tCAN->IF[u8MsgIfNum].DAT_B1 = 0;
sahilmgandhi 18:6a4db94011d3 505 tCAN->IF[u8MsgIfNum].DAT_B2 = 0;
sahilmgandhi 18:6a4db94011d3 506
sahilmgandhi 18:6a4db94011d3 507 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
sahilmgandhi 18:6a4db94011d3 508 ReleaseIF(tCAN, u8MsgIfNum);
sahilmgandhi 18:6a4db94011d3 509
sahilmgandhi 18:6a4db94011d3 510 return TRUE;
sahilmgandhi 18:6a4db94011d3 511 }
sahilmgandhi 18:6a4db94011d3 512
sahilmgandhi 18:6a4db94011d3 513 /**
sahilmgandhi 18:6a4db94011d3 514 * @brief Gets the message
sahilmgandhi 18:6a4db94011d3 515 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 516 * @param[in] u8Release Specifies the message release indicator.
sahilmgandhi 18:6a4db94011d3 517 * This parameter can be one of the following values:
sahilmgandhi 18:6a4db94011d3 518 * TRUE: the message object is released when getting the data.
sahilmgandhi 18:6a4db94011d3 519 * FALSE:the message object is not released.
sahilmgandhi 18:6a4db94011d3 520 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
sahilmgandhi 18:6a4db94011d3 521 * @retval TRUE Success
sahilmgandhi 18:6a4db94011d3 522 * @retval FALSE No any message received
sahilmgandhi 18:6a4db94011d3 523 * @details Gets the message, if received.
sahilmgandhi 18:6a4db94011d3 524 */
sahilmgandhi 18:6a4db94011d3 525 int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 526 {
sahilmgandhi 18:6a4db94011d3 527 uint8_t u8MsgIfNum;
sahilmgandhi 18:6a4db94011d3 528
sahilmgandhi 18:6a4db94011d3 529 if(!CAN_IsNewDataReceived(tCAN, u8MsgObj))
sahilmgandhi 18:6a4db94011d3 530 return FALSE;
sahilmgandhi 18:6a4db94011d3 531
sahilmgandhi 18:6a4db94011d3 532 /* Get and lock a free interface */
sahilmgandhi 18:6a4db94011d3 533 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 534 return FALSE;
sahilmgandhi 18:6a4db94011d3 535
sahilmgandhi 18:6a4db94011d3 536 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
sahilmgandhi 18:6a4db94011d3 537
sahilmgandhi 18:6a4db94011d3 538 /* read the message contents*/
sahilmgandhi 18:6a4db94011d3 539 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_MASK_Msk
sahilmgandhi 18:6a4db94011d3 540 | CAN_IF_CMASK_ARB_Msk
sahilmgandhi 18:6a4db94011d3 541 | CAN_IF_CMASK_CONTROL_Msk
sahilmgandhi 18:6a4db94011d3 542 | CAN_IF_CMASK_CLRINTPND_Msk
sahilmgandhi 18:6a4db94011d3 543 | (u8Release ? CAN_IF_CMASK_TXRQSTNEWDAT_Msk : 0)
sahilmgandhi 18:6a4db94011d3 544 | CAN_IF_CMASK_DATAA_Msk
sahilmgandhi 18:6a4db94011d3 545 | CAN_IF_CMASK_DATAB_Msk;
sahilmgandhi 18:6a4db94011d3 546
sahilmgandhi 18:6a4db94011d3 547 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
sahilmgandhi 18:6a4db94011d3 548
sahilmgandhi 18:6a4db94011d3 549 while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk)
sahilmgandhi 18:6a4db94011d3 550 {
sahilmgandhi 18:6a4db94011d3 551 /*Wait*/
sahilmgandhi 18:6a4db94011d3 552 }
sahilmgandhi 18:6a4db94011d3 553
sahilmgandhi 18:6a4db94011d3 554 if((tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
sahilmgandhi 18:6a4db94011d3 555 {
sahilmgandhi 18:6a4db94011d3 556 /* standard ID*/
sahilmgandhi 18:6a4db94011d3 557 pCanMsg->IdType = CAN_STD_ID;
sahilmgandhi 18:6a4db94011d3 558 pCanMsg->Id = (tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_ID_Msk) >> 2;
sahilmgandhi 18:6a4db94011d3 559 }
sahilmgandhi 18:6a4db94011d3 560 else
sahilmgandhi 18:6a4db94011d3 561 {
sahilmgandhi 18:6a4db94011d3 562 /* extended ID*/
sahilmgandhi 18:6a4db94011d3 563 pCanMsg->IdType = CAN_EXT_ID;
sahilmgandhi 18:6a4db94011d3 564 pCanMsg->Id = (((tCAN->IF[u8MsgIfNum].ARB2) & 0x1FFF) << 16) | tCAN->IF[u8MsgIfNum].ARB1;
sahilmgandhi 18:6a4db94011d3 565 }
sahilmgandhi 18:6a4db94011d3 566
sahilmgandhi 18:6a4db94011d3 567 pCanMsg->DLC = tCAN->IF[u8MsgIfNum].MCON & CAN_IF_MCON_DLC_Msk;
sahilmgandhi 18:6a4db94011d3 568 pCanMsg->Data[0] = tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
sahilmgandhi 18:6a4db94011d3 569 pCanMsg->Data[1] = (tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
sahilmgandhi 18:6a4db94011d3 570 pCanMsg->Data[2] = tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
sahilmgandhi 18:6a4db94011d3 571 pCanMsg->Data[3] = (tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
sahilmgandhi 18:6a4db94011d3 572 pCanMsg->Data[4] = tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
sahilmgandhi 18:6a4db94011d3 573 pCanMsg->Data[5] = (tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
sahilmgandhi 18:6a4db94011d3 574 pCanMsg->Data[6] = tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
sahilmgandhi 18:6a4db94011d3 575 pCanMsg->Data[7] = (tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
sahilmgandhi 18:6a4db94011d3 576
sahilmgandhi 18:6a4db94011d3 577 ReleaseIF(tCAN, u8MsgIfNum);
sahilmgandhi 18:6a4db94011d3 578 return TRUE;
sahilmgandhi 18:6a4db94011d3 579 }
sahilmgandhi 18:6a4db94011d3 580
sahilmgandhi 18:6a4db94011d3 581 /// @endcond HIDDEN_SYMBOLS
sahilmgandhi 18:6a4db94011d3 582
sahilmgandhi 18:6a4db94011d3 583
sahilmgandhi 18:6a4db94011d3 584 /**
sahilmgandhi 18:6a4db94011d3 585 * @brief Set bus baud-rate.
sahilmgandhi 18:6a4db94011d3 586 *
sahilmgandhi 18:6a4db94011d3 587 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 588 * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1~1000KHz.
sahilmgandhi 18:6a4db94011d3 589 *
sahilmgandhi 18:6a4db94011d3 590 * @return u32CurrentBitRate Real baud-rate value.
sahilmgandhi 18:6a4db94011d3 591 *
sahilmgandhi 18:6a4db94011d3 592 * @details The function is used to set bus timing parameter according current clock and target baud-rate.
sahilmgandhi 18:6a4db94011d3 593 */
sahilmgandhi 18:6a4db94011d3 594 uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
sahilmgandhi 18:6a4db94011d3 595 {
sahilmgandhi 18:6a4db94011d3 596 uint8_t u8Tseg1, u8Tseg2;
sahilmgandhi 18:6a4db94011d3 597 uint32_t u32Brp;
sahilmgandhi 18:6a4db94011d3 598 uint32_t u32Value;
sahilmgandhi 18:6a4db94011d3 599
sahilmgandhi 18:6a4db94011d3 600 CAN_EnterInitMode(tCAN, 0);
sahilmgandhi 18:6a4db94011d3 601 SystemCoreClockUpdate();
sahilmgandhi 18:6a4db94011d3 602 u32Value = SystemCoreClock / u32BaudRate;
sahilmgandhi 18:6a4db94011d3 603
sahilmgandhi 18:6a4db94011d3 604 #if 0
sahilmgandhi 18:6a4db94011d3 605 u8Tseg1 = 2;
sahilmgandhi 18:6a4db94011d3 606 u8Tseg2 = 1;
sahilmgandhi 18:6a4db94011d3 607 while(1)
sahilmgandhi 18:6a4db94011d3 608 {
sahilmgandhi 18:6a4db94011d3 609 if(((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0))
sahilmgandhi 18:6a4db94011d3 610 break;
sahilmgandhi 18:6a4db94011d3 611 if(u8Tseg1 < 7)
sahilmgandhi 18:6a4db94011d3 612 u8Tseg2++;
sahilmgandhi 18:6a4db94011d3 613
sahilmgandhi 18:6a4db94011d3 614 if((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0)
sahilmgandhi 18:6a4db94011d3 615 break;
sahilmgandhi 18:6a4db94011d3 616 if(u8Tseg1 < 15)
sahilmgandhi 18:6a4db94011d3 617 u8Tseg1++;
sahilmgandhi 18:6a4db94011d3 618 else
sahilmgandhi 18:6a4db94011d3 619 {
sahilmgandhi 18:6a4db94011d3 620 u8Tseg1 = 2;
sahilmgandhi 18:6a4db94011d3 621 u8Tseg2 = 1;
sahilmgandhi 18:6a4db94011d3 622 break;
sahilmgandhi 18:6a4db94011d3 623 }
sahilmgandhi 18:6a4db94011d3 624 }
sahilmgandhi 18:6a4db94011d3 625 #else
sahilmgandhi 18:6a4db94011d3 626
sahilmgandhi 18:6a4db94011d3 627 /* Fix for most standard baud rates, include 125K */
sahilmgandhi 18:6a4db94011d3 628
sahilmgandhi 18:6a4db94011d3 629 u8Tseg1 = 3;
sahilmgandhi 18:6a4db94011d3 630 u8Tseg2 = 2;
sahilmgandhi 18:6a4db94011d3 631 while(1)
sahilmgandhi 18:6a4db94011d3 632 {
sahilmgandhi 18:6a4db94011d3 633 if(((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0) | (u8Tseg1 >= 15))
sahilmgandhi 18:6a4db94011d3 634 break;
sahilmgandhi 18:6a4db94011d3 635
sahilmgandhi 18:6a4db94011d3 636 u8Tseg1++;
sahilmgandhi 18:6a4db94011d3 637
sahilmgandhi 18:6a4db94011d3 638 if((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0)
sahilmgandhi 18:6a4db94011d3 639 break;
sahilmgandhi 18:6a4db94011d3 640
sahilmgandhi 18:6a4db94011d3 641 if(u8Tseg2 < 7)
sahilmgandhi 18:6a4db94011d3 642 u8Tseg2++;
sahilmgandhi 18:6a4db94011d3 643 }
sahilmgandhi 18:6a4db94011d3 644 #endif
sahilmgandhi 18:6a4db94011d3 645 u32Brp = SystemCoreClock / (u32BaudRate) / (u8Tseg1 + u8Tseg2 + 3) - 1;
sahilmgandhi 18:6a4db94011d3 646
sahilmgandhi 18:6a4db94011d3 647 u32Value = ((uint32_t)u8Tseg2 << CAN_BTIME_TSEG2_Pos) | ((uint32_t)u8Tseg1 << CAN_BTIME_TSEG1_Pos) |
sahilmgandhi 18:6a4db94011d3 648 (u32Brp & CAN_BTIME_BRP_Msk) | (tCAN->BTIME & CAN_BTIME_SJW_Msk);
sahilmgandhi 18:6a4db94011d3 649 tCAN->BTIME = u32Value;
sahilmgandhi 18:6a4db94011d3 650 tCAN->BRPE = (u32Brp >> 6) & 0x0F;
sahilmgandhi 18:6a4db94011d3 651
sahilmgandhi 18:6a4db94011d3 652 CAN_LeaveInitMode(tCAN);
sahilmgandhi 18:6a4db94011d3 653
sahilmgandhi 18:6a4db94011d3 654 return (CAN_GetCANBitRate(tCAN));
sahilmgandhi 18:6a4db94011d3 655 }
sahilmgandhi 18:6a4db94011d3 656
sahilmgandhi 18:6a4db94011d3 657 /**
sahilmgandhi 18:6a4db94011d3 658 * @brief The function is used to disable all CAN interrupt.
sahilmgandhi 18:6a4db94011d3 659 *
sahilmgandhi 18:6a4db94011d3 660 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 661 *
sahilmgandhi 18:6a4db94011d3 662 * @return None
sahilmgandhi 18:6a4db94011d3 663 *
sahilmgandhi 18:6a4db94011d3 664 * @details No Status Change Interrupt and Error Status Interrupt will be generated.
sahilmgandhi 18:6a4db94011d3 665 */
sahilmgandhi 18:6a4db94011d3 666 void CAN_Close(CAN_T *tCAN)
sahilmgandhi 18:6a4db94011d3 667 {
sahilmgandhi 18:6a4db94011d3 668 CAN_DisableInt(tCAN, (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk));
sahilmgandhi 18:6a4db94011d3 669 }
sahilmgandhi 18:6a4db94011d3 670
sahilmgandhi 18:6a4db94011d3 671 /**
sahilmgandhi 18:6a4db94011d3 672 * @brief Set CAN operation mode and target baud-rate.
sahilmgandhi 18:6a4db94011d3 673 *
sahilmgandhi 18:6a4db94011d3 674 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 675 * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1~1000KHz.
sahilmgandhi 18:6a4db94011d3 676 * @param[in] u32Mode The CAN operation mode. Valid values are:
sahilmgandhi 18:6a4db94011d3 677 * - \ref CAN_NORMAL_MODE Normal operation.
sahilmgandhi 18:6a4db94011d3 678 * - \ref CAN_BASIC_MODE Basic mode.
sahilmgandhi 18:6a4db94011d3 679 * @return u32CurrentBitRate Real baud-rate value.
sahilmgandhi 18:6a4db94011d3 680 *
sahilmgandhi 18:6a4db94011d3 681 * @details Set bus timing parameter according current clock and target baud-rate.
sahilmgandhi 18:6a4db94011d3 682 * In Basic mode, IF1 Registers used as Tx Buffer, IF2 Registers used as Rx Buffer.
sahilmgandhi 18:6a4db94011d3 683 */
sahilmgandhi 18:6a4db94011d3 684 uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode)
sahilmgandhi 18:6a4db94011d3 685 {
sahilmgandhi 18:6a4db94011d3 686 uint32_t u32CurrentBitRate;
sahilmgandhi 18:6a4db94011d3 687
sahilmgandhi 18:6a4db94011d3 688 u32CurrentBitRate = CAN_SetBaudRate(tCAN, u32BaudRate);
sahilmgandhi 18:6a4db94011d3 689
sahilmgandhi 18:6a4db94011d3 690 if(u32Mode == CAN_BASIC_MODE)
sahilmgandhi 18:6a4db94011d3 691 CAN_EnterTestMode(tCAN, CAN_TEST_BASIC_Msk);
sahilmgandhi 18:6a4db94011d3 692
sahilmgandhi 18:6a4db94011d3 693 return u32CurrentBitRate;
sahilmgandhi 18:6a4db94011d3 694 }
sahilmgandhi 18:6a4db94011d3 695
sahilmgandhi 18:6a4db94011d3 696 /**
sahilmgandhi 18:6a4db94011d3 697 * @brief The function is used to configure a transmit object.
sahilmgandhi 18:6a4db94011d3 698 *
sahilmgandhi 18:6a4db94011d3 699 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 700 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 701 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
sahilmgandhi 18:6a4db94011d3 702 *
sahilmgandhi 18:6a4db94011d3 703 * @retval FALSE No useful interface.
sahilmgandhi 18:6a4db94011d3 704 * @retval TRUE Config message object success.
sahilmgandhi 18:6a4db94011d3 705 *
sahilmgandhi 18:6a4db94011d3 706 * @details The two sets of interface registers (IF1 and IF2) control the software access to the Message RAM.
sahilmgandhi 18:6a4db94011d3 707 * They buffer the data to be transferred to and from the RAM, avoiding conflicts between software accesses and message reception/transmission.
sahilmgandhi 18:6a4db94011d3 708 */
sahilmgandhi 18:6a4db94011d3 709 int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 710 {
sahilmgandhi 18:6a4db94011d3 711 uint8_t u8MsgIfNum;
sahilmgandhi 18:6a4db94011d3 712
sahilmgandhi 18:6a4db94011d3 713 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 714 return FALSE;
sahilmgandhi 18:6a4db94011d3 715
sahilmgandhi 18:6a4db94011d3 716 /* update the contents needed for transmission*/
sahilmgandhi 18:6a4db94011d3 717 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
sahilmgandhi 18:6a4db94011d3 718 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
sahilmgandhi 18:6a4db94011d3 719
sahilmgandhi 18:6a4db94011d3 720 if(pCanMsg->IdType == CAN_STD_ID)
sahilmgandhi 18:6a4db94011d3 721 {
sahilmgandhi 18:6a4db94011d3 722 /* standard ID*/
sahilmgandhi 18:6a4db94011d3 723 tCAN->IF[u8MsgIfNum].ARB1 = 0;
sahilmgandhi 18:6a4db94011d3 724 tCAN->IF[u8MsgIfNum].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) | CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_MSGVAL_Msk;
sahilmgandhi 18:6a4db94011d3 725 }
sahilmgandhi 18:6a4db94011d3 726 else
sahilmgandhi 18:6a4db94011d3 727 {
sahilmgandhi 18:6a4db94011d3 728 /* extended ID*/
sahilmgandhi 18:6a4db94011d3 729 tCAN->IF[u8MsgIfNum].ARB1 = (pCanMsg->Id) & 0xFFFF;
sahilmgandhi 18:6a4db94011d3 730 tCAN->IF[u8MsgIfNum].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 |
sahilmgandhi 18:6a4db94011d3 731 CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_XTD_Msk | CAN_IF_ARB2_MSGVAL_Msk;
sahilmgandhi 18:6a4db94011d3 732 }
sahilmgandhi 18:6a4db94011d3 733
sahilmgandhi 18:6a4db94011d3 734 if(pCanMsg->FrameType)
sahilmgandhi 18:6a4db94011d3 735 tCAN->IF[u8MsgIfNum].ARB2 |= CAN_IF_ARB2_DIR_Msk;
sahilmgandhi 18:6a4db94011d3 736 else
sahilmgandhi 18:6a4db94011d3 737 tCAN->IF[u8MsgIfNum].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
sahilmgandhi 18:6a4db94011d3 738
sahilmgandhi 18:6a4db94011d3 739 tCAN->IF[u8MsgIfNum].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0];
sahilmgandhi 18:6a4db94011d3 740 tCAN->IF[u8MsgIfNum].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2];
sahilmgandhi 18:6a4db94011d3 741 tCAN->IF[u8MsgIfNum].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4];
sahilmgandhi 18:6a4db94011d3 742 tCAN->IF[u8MsgIfNum].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6];
sahilmgandhi 18:6a4db94011d3 743
sahilmgandhi 18:6a4db94011d3 744 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_NEWDAT_Msk | pCanMsg->DLC | CAN_IF_MCON_TXIE_Msk | CAN_IF_MCON_EOB_Msk;
sahilmgandhi 18:6a4db94011d3 745 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
sahilmgandhi 18:6a4db94011d3 746
sahilmgandhi 18:6a4db94011d3 747 ReleaseIF(tCAN, u8MsgIfNum);
sahilmgandhi 18:6a4db94011d3 748 return TRUE;
sahilmgandhi 18:6a4db94011d3 749 }
sahilmgandhi 18:6a4db94011d3 750
sahilmgandhi 18:6a4db94011d3 751 /**
sahilmgandhi 18:6a4db94011d3 752 * @brief Set transmit request bit.
sahilmgandhi 18:6a4db94011d3 753 *
sahilmgandhi 18:6a4db94011d3 754 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 755 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 756 *
sahilmgandhi 18:6a4db94011d3 757 * @return TRUE: Start transmit message.
sahilmgandhi 18:6a4db94011d3 758 *
sahilmgandhi 18:6a4db94011d3 759 * @details If a transmission is requested by programming bit TxRqst/NewDat (IFn_CMASK[2]), the TxRqst (IFn_MCON[8]) will be ignored.
sahilmgandhi 18:6a4db94011d3 760 */
sahilmgandhi 18:6a4db94011d3 761 int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
sahilmgandhi 18:6a4db94011d3 762 {
sahilmgandhi 18:6a4db94011d3 763 uint8_t u8MsgIfNum;
sahilmgandhi 18:6a4db94011d3 764
sahilmgandhi 18:6a4db94011d3 765 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 766 return FALSE;
sahilmgandhi 18:6a4db94011d3 767
sahilmgandhi 18:6a4db94011d3 768 tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk);
sahilmgandhi 18:6a4db94011d3 769
sahilmgandhi 18:6a4db94011d3 770 /* read the message contents*/
sahilmgandhi 18:6a4db94011d3 771 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk
sahilmgandhi 18:6a4db94011d3 772 | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
sahilmgandhi 18:6a4db94011d3 773
sahilmgandhi 18:6a4db94011d3 774 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
sahilmgandhi 18:6a4db94011d3 775
sahilmgandhi 18:6a4db94011d3 776 while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk)
sahilmgandhi 18:6a4db94011d3 777 {
sahilmgandhi 18:6a4db94011d3 778 /*Wait*/
sahilmgandhi 18:6a4db94011d3 779 }
sahilmgandhi 18:6a4db94011d3 780 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
sahilmgandhi 18:6a4db94011d3 781 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
sahilmgandhi 18:6a4db94011d3 782
sahilmgandhi 18:6a4db94011d3 783 ReleaseIF(tCAN, u8MsgIfNum);
sahilmgandhi 18:6a4db94011d3 784 return TRUE;
sahilmgandhi 18:6a4db94011d3 785 }
sahilmgandhi 18:6a4db94011d3 786
sahilmgandhi 18:6a4db94011d3 787 /**
sahilmgandhi 18:6a4db94011d3 788 * @brief Enable CAN interrupt.
sahilmgandhi 18:6a4db94011d3 789 *
sahilmgandhi 18:6a4db94011d3 790 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 791 * @param[in] u32Mask Interrupt Mask. Valid values are:
sahilmgandhi 18:6a4db94011d3 792 * - \ref CAN_CON_IE_Msk Module interrupt enable.
sahilmgandhi 18:6a4db94011d3 793 * - \ref CAN_CON_SIE_Msk Status change interrupt enable.
sahilmgandhi 18:6a4db94011d3 794 * - \ref CAN_CON_EIE_Msk Error interrupt enable.
sahilmgandhi 18:6a4db94011d3 795 *
sahilmgandhi 18:6a4db94011d3 796 * @return None
sahilmgandhi 18:6a4db94011d3 797 *
sahilmgandhi 18:6a4db94011d3 798 * @details The application software has two possibilities to follow the source of a message interrupt.
sahilmgandhi 18:6a4db94011d3 799 * First, it can follow the IntId in the Interrupt Register and second it can poll the Interrupt Pending Register.
sahilmgandhi 18:6a4db94011d3 800 */
sahilmgandhi 18:6a4db94011d3 801 void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
sahilmgandhi 18:6a4db94011d3 802 {
sahilmgandhi 18:6a4db94011d3 803 tCAN->CON = (tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)) |
sahilmgandhi 18:6a4db94011d3 804 (u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk));
sahilmgandhi 18:6a4db94011d3 805 }
sahilmgandhi 18:6a4db94011d3 806
sahilmgandhi 18:6a4db94011d3 807 /**
sahilmgandhi 18:6a4db94011d3 808 * @brief Disable CAN interrupt.
sahilmgandhi 18:6a4db94011d3 809 *
sahilmgandhi 18:6a4db94011d3 810 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 811 * @param[in] u32Mask Interrupt Mask. (CAN_CON_IE_Msk / CAN_CON_SIE_Msk / CAN_CON_EIE_Msk).
sahilmgandhi 18:6a4db94011d3 812 *
sahilmgandhi 18:6a4db94011d3 813 * @return None
sahilmgandhi 18:6a4db94011d3 814 *
sahilmgandhi 18:6a4db94011d3 815 * @details The interrupt remains active until the Interrupt Register is back to value zero (the cause of the interrupt is reset) or until IE is reset.
sahilmgandhi 18:6a4db94011d3 816 */
sahilmgandhi 18:6a4db94011d3 817 void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
sahilmgandhi 18:6a4db94011d3 818 {
sahilmgandhi 18:6a4db94011d3 819 tCAN->CON = tCAN->CON & ~((u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)));
sahilmgandhi 18:6a4db94011d3 820 }
sahilmgandhi 18:6a4db94011d3 821
sahilmgandhi 18:6a4db94011d3 822
sahilmgandhi 18:6a4db94011d3 823 /**
sahilmgandhi 18:6a4db94011d3 824 * @brief The function is used to configure a receive message object.
sahilmgandhi 18:6a4db94011d3 825 *
sahilmgandhi 18:6a4db94011d3 826 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 827 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 828 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
sahilmgandhi 18:6a4db94011d3 829 * - \ref CAN_STD_ID The 11-bit identifier.
sahilmgandhi 18:6a4db94011d3 830 * - \ref CAN_EXT_ID The 29-bit identifier.
sahilmgandhi 18:6a4db94011d3 831 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 832 *
sahilmgandhi 18:6a4db94011d3 833 * @retval FALSE No useful interface.
sahilmgandhi 18:6a4db94011d3 834 * @retval TRUE Configure a receive message object success.
sahilmgandhi 18:6a4db94011d3 835 *
sahilmgandhi 18:6a4db94011d3 836 * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13])
sahilmgandhi 18:6a4db94011d3 837 * will be set when a received Data Frame is accepted and stored in the Message Object.
sahilmgandhi 18:6a4db94011d3 838 */
sahilmgandhi 18:6a4db94011d3 839 int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID)
sahilmgandhi 18:6a4db94011d3 840 {
sahilmgandhi 18:6a4db94011d3 841 uint32_t u32TimeOutCount = 0;
sahilmgandhi 18:6a4db94011d3 842
sahilmgandhi 18:6a4db94011d3 843 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, TRUE) == FALSE)
sahilmgandhi 18:6a4db94011d3 844 {
sahilmgandhi 18:6a4db94011d3 845 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
sahilmgandhi 18:6a4db94011d3 846 }
sahilmgandhi 18:6a4db94011d3 847
sahilmgandhi 18:6a4db94011d3 848 return TRUE;
sahilmgandhi 18:6a4db94011d3 849 }
sahilmgandhi 18:6a4db94011d3 850
sahilmgandhi 18:6a4db94011d3 851 /**
sahilmgandhi 18:6a4db94011d3 852 * @brief The function is used to configure a receive message object.
sahilmgandhi 18:6a4db94011d3 853 *
sahilmgandhi 18:6a4db94011d3 854 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 855 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 856 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
sahilmgandhi 18:6a4db94011d3 857 * - \ref CAN_STD_ID The 11-bit identifier.
sahilmgandhi 18:6a4db94011d3 858 * - \ref CAN_EXT_ID The 29-bit identifier.
sahilmgandhi 18:6a4db94011d3 859 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 860 * @param[in] u32IDMask Specifies the identifier mask used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 861 *
sahilmgandhi 18:6a4db94011d3 862 * @retval FALSE No useful interface.
sahilmgandhi 18:6a4db94011d3 863 * @retval TRUE Configure a receive message object success.
sahilmgandhi 18:6a4db94011d3 864 *
sahilmgandhi 18:6a4db94011d3 865 * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13])
sahilmgandhi 18:6a4db94011d3 866 * will be set when a received Data Frame is accepted and stored in the Message Object.
sahilmgandhi 18:6a4db94011d3 867 */
sahilmgandhi 18:6a4db94011d3 868 int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask)
sahilmgandhi 18:6a4db94011d3 869 {
sahilmgandhi 18:6a4db94011d3 870 uint32_t u32TimeOutCount = 0;
sahilmgandhi 18:6a4db94011d3 871
sahilmgandhi 18:6a4db94011d3 872 while(CAN_SetRxMsgObjAndMsk(tCAN, u32MsgNum, u32IDType, u32ID, u32IDMask, TRUE) == FALSE)
sahilmgandhi 18:6a4db94011d3 873 {
sahilmgandhi 18:6a4db94011d3 874 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
sahilmgandhi 18:6a4db94011d3 875 }
sahilmgandhi 18:6a4db94011d3 876
sahilmgandhi 18:6a4db94011d3 877 return TRUE;
sahilmgandhi 18:6a4db94011d3 878 }
sahilmgandhi 18:6a4db94011d3 879
sahilmgandhi 18:6a4db94011d3 880 /**
sahilmgandhi 18:6a4db94011d3 881 * @brief The function is used to configure several receive message objects.
sahilmgandhi 18:6a4db94011d3 882 *
sahilmgandhi 18:6a4db94011d3 883 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 884 * @param[in] u32MsgNum The starting MSG RAM number(0 ~ 31).
sahilmgandhi 18:6a4db94011d3 885 * @param[in] u32MsgCount the number of MSG RAM of the FIFO.
sahilmgandhi 18:6a4db94011d3 886 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
sahilmgandhi 18:6a4db94011d3 887 * - \ref CAN_STD_ID The 11-bit identifier.
sahilmgandhi 18:6a4db94011d3 888 * - \ref CAN_EXT_ID The 29-bit identifier.
sahilmgandhi 18:6a4db94011d3 889 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
sahilmgandhi 18:6a4db94011d3 890 *
sahilmgandhi 18:6a4db94011d3 891 * @retval FALSE No useful interface.
sahilmgandhi 18:6a4db94011d3 892 * @retval TRUE Configure receive message objects success.
sahilmgandhi 18:6a4db94011d3 893 *
sahilmgandhi 18:6a4db94011d3 894 * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception
sahilmgandhi 18:6a4db94011d3 895 * and transmission by buffering the data to be transferred.
sahilmgandhi 18:6a4db94011d3 896 */
sahilmgandhi 18:6a4db94011d3 897 int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID)
sahilmgandhi 18:6a4db94011d3 898 {
sahilmgandhi 18:6a4db94011d3 899 uint32_t i = 0;
sahilmgandhi 18:6a4db94011d3 900 uint32_t u32TimeOutCount;
sahilmgandhi 18:6a4db94011d3 901 uint32_t u32EOB_Flag = 0;
sahilmgandhi 18:6a4db94011d3 902
sahilmgandhi 18:6a4db94011d3 903 for(i = 1; i < u32MsgCount; i++)
sahilmgandhi 18:6a4db94011d3 904 {
sahilmgandhi 18:6a4db94011d3 905 u32TimeOutCount = 0;
sahilmgandhi 18:6a4db94011d3 906
sahilmgandhi 18:6a4db94011d3 907 u32MsgNum += (i - 1);
sahilmgandhi 18:6a4db94011d3 908
sahilmgandhi 18:6a4db94011d3 909 if(i == u32MsgCount) u32EOB_Flag = 1;
sahilmgandhi 18:6a4db94011d3 910
sahilmgandhi 18:6a4db94011d3 911 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, u32EOB_Flag) == FALSE)
sahilmgandhi 18:6a4db94011d3 912 {
sahilmgandhi 18:6a4db94011d3 913 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
sahilmgandhi 18:6a4db94011d3 914 }
sahilmgandhi 18:6a4db94011d3 915 }
sahilmgandhi 18:6a4db94011d3 916
sahilmgandhi 18:6a4db94011d3 917 return TRUE;
sahilmgandhi 18:6a4db94011d3 918 }
sahilmgandhi 18:6a4db94011d3 919
sahilmgandhi 18:6a4db94011d3 920
sahilmgandhi 18:6a4db94011d3 921 /**
sahilmgandhi 18:6a4db94011d3 922 * @brief Send CAN message.
sahilmgandhi 18:6a4db94011d3 923 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 924 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 925 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
sahilmgandhi 18:6a4db94011d3 926 *
sahilmgandhi 18:6a4db94011d3 927 * @retval FALSE 1. When operation in basic mode: Transmit message time out. \n
sahilmgandhi 18:6a4db94011d3 928 * 2. When operation in normal mode: No useful interface. \n
sahilmgandhi 18:6a4db94011d3 929 * @retval TRUE Transmit Message success.
sahilmgandhi 18:6a4db94011d3 930 *
sahilmgandhi 18:6a4db94011d3 931 * @details The receive/transmit priority for the Message Objects is attached to the message number.
sahilmgandhi 18:6a4db94011d3 932 * Message Object 1 has the highest priority, while Message Object 32 has the lowest priority.
sahilmgandhi 18:6a4db94011d3 933 */
sahilmgandhi 18:6a4db94011d3 934 int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 935 {
sahilmgandhi 18:6a4db94011d3 936 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
sahilmgandhi 18:6a4db94011d3 937 {
sahilmgandhi 18:6a4db94011d3 938 return (CAN_BasicSendMsg(tCAN, pCanMsg));
sahilmgandhi 18:6a4db94011d3 939 }
sahilmgandhi 18:6a4db94011d3 940 else
sahilmgandhi 18:6a4db94011d3 941 {
sahilmgandhi 18:6a4db94011d3 942 if(CAN_SetTxMsg(tCAN, u32MsgNum, pCanMsg) == FALSE)
sahilmgandhi 18:6a4db94011d3 943 return FALSE;
sahilmgandhi 18:6a4db94011d3 944 CAN_TriggerTxMsg(tCAN, u32MsgNum);
sahilmgandhi 18:6a4db94011d3 945 }
sahilmgandhi 18:6a4db94011d3 946
sahilmgandhi 18:6a4db94011d3 947 return TRUE;
sahilmgandhi 18:6a4db94011d3 948 }
sahilmgandhi 18:6a4db94011d3 949
sahilmgandhi 18:6a4db94011d3 950
sahilmgandhi 18:6a4db94011d3 951 /**
sahilmgandhi 18:6a4db94011d3 952 * @brief Gets the message, if received.
sahilmgandhi 18:6a4db94011d3 953 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 954 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 955 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
sahilmgandhi 18:6a4db94011d3 956 *
sahilmgandhi 18:6a4db94011d3 957 * @retval FALSE No any message received.
sahilmgandhi 18:6a4db94011d3 958 * @retval TRUE Receive Message success.
sahilmgandhi 18:6a4db94011d3 959 *
sahilmgandhi 18:6a4db94011d3 960 * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception
sahilmgandhi 18:6a4db94011d3 961 * and transmission by buffering the data to be transferred.
sahilmgandhi 18:6a4db94011d3 962 */
sahilmgandhi 18:6a4db94011d3 963 int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
sahilmgandhi 18:6a4db94011d3 964 {
sahilmgandhi 18:6a4db94011d3 965 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
sahilmgandhi 18:6a4db94011d3 966 {
sahilmgandhi 18:6a4db94011d3 967 return (CAN_BasicReceiveMsg(tCAN, pCanMsg));
sahilmgandhi 18:6a4db94011d3 968 }
sahilmgandhi 18:6a4db94011d3 969 else
sahilmgandhi 18:6a4db94011d3 970 {
sahilmgandhi 18:6a4db94011d3 971 return CAN_ReadMsgObj(tCAN, u32MsgNum, TRUE, pCanMsg);
sahilmgandhi 18:6a4db94011d3 972 }
sahilmgandhi 18:6a4db94011d3 973 }
sahilmgandhi 18:6a4db94011d3 974
sahilmgandhi 18:6a4db94011d3 975 /**
sahilmgandhi 18:6a4db94011d3 976 * @brief Clear interrupt pending bit.
sahilmgandhi 18:6a4db94011d3 977 * @param[in] tCAN The pointer to CAN module base address.
sahilmgandhi 18:6a4db94011d3 978 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
sahilmgandhi 18:6a4db94011d3 979 *
sahilmgandhi 18:6a4db94011d3 980 * @return None
sahilmgandhi 18:6a4db94011d3 981 *
sahilmgandhi 18:6a4db94011d3 982 * @details An interrupt remains pending until the application software has cleared it.
sahilmgandhi 18:6a4db94011d3 983 */
sahilmgandhi 18:6a4db94011d3 984 void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
sahilmgandhi 18:6a4db94011d3 985 {
sahilmgandhi 18:6a4db94011d3 986 uint32_t u32MsgIfNum;
sahilmgandhi 18:6a4db94011d3 987
sahilmgandhi 18:6a4db94011d3 988 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2)
sahilmgandhi 18:6a4db94011d3 989 u32MsgIfNum = 0;
sahilmgandhi 18:6a4db94011d3 990
sahilmgandhi 18:6a4db94011d3 991 tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
sahilmgandhi 18:6a4db94011d3 992 tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum;
sahilmgandhi 18:6a4db94011d3 993
sahilmgandhi 18:6a4db94011d3 994 ReleaseIF(tCAN, u32MsgIfNum);
sahilmgandhi 18:6a4db94011d3 995 }
sahilmgandhi 18:6a4db94011d3 996
sahilmgandhi 18:6a4db94011d3 997
sahilmgandhi 18:6a4db94011d3 998 /*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */
sahilmgandhi 18:6a4db94011d3 999
sahilmgandhi 18:6a4db94011d3 1000 /*@}*/ /* end of group CAN_Driver */
sahilmgandhi 18:6a4db94011d3 1001
sahilmgandhi 18:6a4db94011d3 1002 /*@}*/ /* end of group Standard_Driver */
sahilmgandhi 18:6a4db94011d3 1003
sahilmgandhi 18:6a4db94011d3 1004 /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/
sahilmgandhi 18:6a4db94011d3 1005