CAN_LPC18xx.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 20. April 2016
  19. * $Revision: V1.4
  20. *
  21. * Driver: Driver_CAN0/1
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: CAN Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value CAN Interface
  29. * --------------------- ----- -------------
  30. * Connect to hardware via Driver_CAN# = 0 use CAN0
  31. * Connect to hardware via Driver_CAN# = 1 use CAN1
  32. * --------------------------------------------------------------------------
  33. * Defines used for driver configuration (at compile time):
  34. *
  35. * CAN_CLOCK_TOLERANCE: defines maximum allowed clock tolerance in 1/1024 steps
  36. * - default value: 15 (approx. 1.5 %)
  37. * CAN0_OBJ_NUM: number of message objects used by CAN0 controller
  38. * this value can be reduced to save some RAM space
  39. * - default value: 32 (also this is maximum value)
  40. * CAN1_OBJ_NUM: number of message objects used by CAN1 controller
  41. * this value can be reduced to save some RAM space
  42. * - default value: 32 (also this is maximum value)
  43. * -------------------------------------------------------------------------- */
  44. /* History:
  45. * Version 1.4
  46. * Corrected receive overrun clearing and signaling
  47. * Version 1.3
  48. * Corrected interrupt routine (status interrupt could case lockup)
  49. * Version 1.2
  50. * Corrected functionality when NULL pointer is provided for one or both
  51. * signal callbacks in Initialize function call
  52. * Version 1.1
  53. * Corrected CAN1 IRQ routine
  54. * Corrected MessageSend function to return busy if transmission is in progress
  55. * Version 1.0
  56. * Initial release
  57. */
  58. #include "CAN_LPC18xx.h"
  59. // Externally overridable configuration definitions
  60. // Maximum allowed clock tolerance in 1/1024 steps
  61. #ifndef CAN_CLOCK_TOLERANCE
  62. #define CAN_CLOCK_TOLERANCE (15U) // 15/1024 approx. 1.5 %
  63. #endif
  64. // Maximum number of Message Objects used for CAN0 controller
  65. #ifndef CAN0_OBJ_NUM
  66. #define CAN0_OBJ_NUM (32U)
  67. #endif
  68. #if (CAN0_OBJ_NUM > 32U)
  69. #error Too many Message Objects defined for CAN0, maximum number of Message Objects is 32 !!!
  70. #endif
  71. // Maximum number of Message Objects used for CAN1 controller
  72. #ifndef CAN1_OBJ_NUM
  73. #define CAN1_OBJ_NUM (32U)
  74. #endif
  75. #if (CAN1_OBJ_NUM > 32U)
  76. #error Too many Message Objects defined for CAN1, maximum number of Message Objects is 32 !!!
  77. #endif
  78. // External Functions
  79. extern uint32_t GetClockFreq (uint32_t clk_src);
  80. // CAN Driver ******************************************************************
  81. #define ARM_CAN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,4) // CAN driver version
  82. // Driver Version
  83. static const ARM_DRIVER_VERSION can_driver_version = { ARM_CAN_API_VERSION, ARM_CAN_DRV_VERSION };
  84. // Driver Capabilities
  85. static const ARM_CAN_CAPABILITIES can_driver_capabilities[2] = {
  86. { // CAN0 driver capabilities
  87. CAN0_OBJ_NUM, // Number of CAN Objects available
  88. 0U, // Does not support reentrant calls to ARM_CAN_MessageSend, ARM_CAN_MessageRead, ARM_CAN_ObjectConfigure and abort message sending used by ARM_CAN_Control.
  89. 0U, // Does not support CAN with flexible data-rate mode (CAN_FD)
  90. 0U, // Does not support restricted operation mode
  91. 1U, // Supports bus monitoring mode
  92. 1U, // Supports internal loopback mode
  93. 1U, // Supports external loopback mode
  94. },
  95. { // CAN1 driver capabilities
  96. CAN1_OBJ_NUM, // Number of CAN Objects available
  97. 0U, // Does not support reentrant calls to ARM_CAN_MessageSend, ARM_CAN_MessageRead, ARM_CAN_ObjectConfigure and abort message sending used by ARM_CAN_Control.
  98. 0U, // Does not support CAN with flexible data-rate mode (CAN_FD)
  99. 0U, // Does not support restricted operation mode
  100. 1U, // Supports bus monitoring mode
  101. 1U, // Supports internal loopback mode
  102. 1U, // Supports external loopback mode
  103. }
  104. };
  105. // Object Capabilities
  106. static const ARM_CAN_OBJ_CAPABILITIES can_object_capabilities = {
  107. 1U, // Object supports transmission
  108. 1U, // Object supports reception
  109. 1U, // Object supports RTR reception and automatic Data transmission
  110. 1U, // Object supports RTR transmission and automatic Data reception
  111. 0U, // Object does not allow assignment of multiple filters to it
  112. 1U, // Object supports exact identifier filtering
  113. 0U, // Object does not support range identifier filtering
  114. 1U, // Object supports mask identifier filtering
  115. 1U // Object can buffer 1 message
  116. };
  117. static LPC_C_CANn_Type * const ptr_CANx[2] = { (LPC_C_CANn_Type *)LPC_C_CAN0_BASE, (LPC_C_CANn_Type *)LPC_C_CAN1_BASE };
  118. // Local variables and structures
  119. static uint8_t can_driver_powered [CAN_CTRL_NUM];
  120. static uint8_t can_driver_initialized[CAN_CTRL_NUM];
  121. static uint8_t can_obj_cfg [CAN_CTRL_NUM][(CAN0_OBJ_NUM > CAN1_OBJ_NUM) ? CAN0_OBJ_NUM : CAN1_OBJ_NUM];
  122. static uint8_t can_stat_last [CAN_CTRL_NUM];
  123. static ARM_CAN_SignalUnitEvent_t CAN_SignalUnitEvent [CAN_CTRL_NUM];
  124. static ARM_CAN_SignalObjectEvent_t CAN_SignalObjectEvent [CAN_CTRL_NUM];
  125. // Helper Functions
  126. /**
  127. \fn void CANx_HW_Reset (uint8_t x)
  128. \brief Reset CAN hardware (reset message objects and clear interrupts).
  129. \param[in] x Controller number (0..1)
  130. */
  131. static void CANx_HW_Reset (uint8_t x) {
  132. LPC_C_CANn_Type *ptr_CAN;
  133. uint8_t obj, obj_end;
  134. ptr_CAN = ptr_CANx[x];
  135. can_stat_last[x] = 0U;
  136. ptr_CAN->CNTL = 1U; // Initialization
  137. obj_end = ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM);
  138. for (obj = 0U; obj < obj_end; obj++) {
  139. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  140. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_ARB_Msk | IF_CMDMSK_WR_RD_Msk;
  141. ptr_CAN->IF1_ARB2 = 0U; // Invalidate message object (MSGVAL = 0)
  142. ptr_CAN->IF1_CMDREQ = obj + 1U;
  143. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  144. ptr_CAN->IF1_CMDMSK_R = IF_CMDMSK_CLRINTPND_Msk; // Clear interrupt pending
  145. ptr_CAN->IF1_CMDREQ = obj + 1U;
  146. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  147. can_obj_cfg[x][obj] = ARM_CAN_OBJ_INACTIVE;
  148. }
  149. ptr_CAN->STAT = 0U; // Clear interrupt status
  150. }
  151. /**
  152. \fn void CANx_AbortSendMessage (uint32_t obj, uint8_t x)
  153. \brief Abort send message.
  154. \param[in] obj Message object index
  155. \param[in] x Controller number (0..1)
  156. */
  157. static void CANx_AbortSendMessage (uint32_t obj, uint8_t x) {
  158. LPC_C_CANn_Type *ptr_CAN;
  159. ptr_CAN = ptr_CANx[x];
  160. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  161. ptr_CAN->IF1_CMDMSK_R = IF_CMDMSK_CTRL_Msk;
  162. ptr_CAN->IF1_CMDREQ = obj + 1U;
  163. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  164. ptr_CAN->IF1_MCTRL &= ~IF_MCTRL_TXRQST_Msk; // Clear TXRQST bit
  165. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_CTRL_Msk |
  166. IF_CMDMSK_WR_RD_Msk;
  167. ptr_CAN->IF1_CMDREQ = obj + 1U;
  168. while ((ptr_CAN->IF1_CMDREQ & IF_CMDREQ_BUSY_Msk) != 0U);
  169. }
  170. // CAN Driver Functions
  171. /**
  172. \fn ARM_DRIVER_VERSION CAN_GetVersion (void)
  173. \brief Get driver version.
  174. \return ARM_DRIVER_VERSION
  175. */
  176. static ARM_DRIVER_VERSION CAN_GetVersion (void) { return can_driver_version; }
  177. /**
  178. \fn ARM_CAN_CAPABILITIES CAN0_GetCapabilities (void)
  179. \fn ARM_CAN_CAPABILITIES CAN1_GetCapabilities (void)
  180. \brief Get driver capabilities.
  181. \return ARM_CAN_CAPABILITIES
  182. */
  183. #if (RTE_CAN_CAN0 == 1U)
  184. static ARM_CAN_CAPABILITIES CAN0_GetCapabilities (void) { return can_driver_capabilities[0U]; }
  185. #endif
  186. #if (RTE_CAN_CAN1 == 1U)
  187. static ARM_CAN_CAPABILITIES CAN1_GetCapabilities (void) { return can_driver_capabilities[1U]; }
  188. #endif
  189. /**
  190. \fn int32_t CANx_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
  191. ARM_CAN_SignalObjectEvent_t cb_object_event,
  192. uint8_t x)
  193. \brief Initialize CAN interface and register signal (callback) functions.
  194. \param[in] cb_unit_event Pointer to ARM_CAN_SignalUnitEvent callback function
  195. \param[in] cb_object_event Pointer to ARM_CAN_SignalObjectEvent callback function
  196. \param[in] x Controller number (0..1)
  197. \return execution status
  198. */
  199. static int32_t CANx_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
  200. ARM_CAN_SignalObjectEvent_t cb_object_event,
  201. uint8_t x) {
  202. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  203. if (can_driver_initialized[x] != 0U) { return ARM_DRIVER_OK; }
  204. CAN_SignalUnitEvent [x] = cb_unit_event;
  205. CAN_SignalObjectEvent[x] = cb_object_event;
  206. if (x == 0U) {
  207. #if (RTE_CAN0_RD_PIN_EN == 1)
  208. SCU_PinConfigure (RTE_CAN0_RD_PORT, RTE_CAN0_RD_BIT, RTE_CAN0_RD_FUNC | SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN);
  209. #endif
  210. #if (RTE_CAN0_TD_PIN_EN == 1)
  211. SCU_PinConfigure (RTE_CAN0_TD_PORT, RTE_CAN0_TD_BIT, RTE_CAN0_TD_FUNC | SCU_PIN_CFG_PULLUP_DIS);
  212. #endif
  213. } else {
  214. #if (RTE_CAN1_RD_PIN_EN == 1)
  215. SCU_PinConfigure (RTE_CAN1_RD_PORT, RTE_CAN1_RD_BIT, RTE_CAN1_RD_FUNC | SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN);
  216. #endif
  217. #if (RTE_CAN1_TD_PIN_EN == 1)
  218. SCU_PinConfigure (RTE_CAN1_TD_PORT, RTE_CAN1_TD_BIT, RTE_CAN1_TD_FUNC | SCU_PIN_CFG_PULLUP_DIS);
  219. #endif
  220. }
  221. can_driver_initialized[x] = 1U;
  222. return ARM_DRIVER_OK;
  223. }
  224. #if (RTE_CAN_CAN0 == 1U)
  225. static int32_t CAN0_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event, ARM_CAN_SignalObjectEvent_t cb_object_event) { return CANx_Initialize (cb_unit_event, cb_object_event, 0U); }
  226. #endif
  227. #if (RTE_CAN_CAN1 == 1U)
  228. static int32_t CAN1_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event, ARM_CAN_SignalObjectEvent_t cb_object_event) { return CANx_Initialize (cb_unit_event, cb_object_event, 1U); }
  229. #endif
  230. /**
  231. \fn int32_t CANx_Uninitialize (uint8_t x)
  232. \brief De-initialize CAN interface.
  233. \param[in] x Controller number (0..1)
  234. \return execution status
  235. */
  236. static int32_t CANx_Uninitialize (uint8_t x) {
  237. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  238. if (x == 0U) {
  239. #if (RTE_CAN0_RD_PIN_EN == 1)
  240. SCU_PinConfigure (RTE_CAN0_RD_PORT, RTE_CAN0_RD_BIT, 0U);
  241. #endif
  242. #if (RTE_CAN0_TD_PIN_EN == 1)
  243. SCU_PinConfigure (RTE_CAN0_TD_PORT, RTE_CAN0_TD_BIT, 0U);
  244. #endif
  245. } else {
  246. #if (RTE_CAN1_RD_PIN_EN == 1)
  247. SCU_PinConfigure (RTE_CAN1_RD_PORT, RTE_CAN1_RD_BIT, 0U);
  248. #endif
  249. #if (RTE_CAN1_TD_PIN_EN == 1)
  250. SCU_PinConfigure (RTE_CAN1_TD_PORT, RTE_CAN1_TD_BIT, 0U);
  251. #endif
  252. }
  253. can_driver_initialized[x] = 0U;
  254. return ARM_DRIVER_OK;
  255. }
  256. #if (RTE_CAN_CAN0 == 1U)
  257. static int32_t CAN0_Uninitialize (void) { return CANx_Uninitialize (0U); }
  258. #endif
  259. #if (RTE_CAN_CAN1 == 1U)
  260. static int32_t CAN1_Uninitialize (void) { return CANx_Uninitialize (1U); }
  261. #endif
  262. /**
  263. \fn int32_t CANx_PowerControl (ARM_POWER_STATE state, uint8_t x)
  264. \brief Control CAN interface power.
  265. \param[in] state Power state
  266. - ARM_POWER_OFF : power off: no operation possible
  267. - ARM_POWER_LOW : low power mode: retain state, detect and signal wake-up events
  268. - ARM_POWER_FULL : power on: full operation at maximum performance
  269. \param[in] x Controller number (0..1)
  270. \return execution status
  271. */
  272. static int32_t CANx_PowerControl (ARM_POWER_STATE state, uint8_t x) {
  273. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  274. switch (state) {
  275. case ARM_POWER_OFF:
  276. can_driver_powered[x] = 0U;
  277. if (x == 0U) {
  278. NVIC_DisableIRQ (C_CAN0_IRQn);
  279. LPC_CGU->BASE_APB3_CLK = (1U << 11) | // Auto-block enable
  280. (9U << 24) ; // Clock source: PLL1
  281. LPC_CCU1->CLK_APB3_CAN0_CFG |= 1U; // Enable C_CAN0 Base Clock
  282. while ((LPC_CCU1->CLK_APB3_CAN0_CFG & 1U) == 0U);
  283. } else {
  284. NVIC_DisableIRQ (C_CAN1_IRQn);
  285. LPC_CGU->BASE_APB1_CLK = (1U << 11) | // Auto-block enable
  286. (9U << 24) ; // Clock source: PLL1
  287. LPC_CCU1->CLK_APB1_CAN1_CFG |= 1U; // Enable C_CAN1 Base Clock
  288. while ((LPC_CCU1->CLK_APB1_CAN1_CFG & 1U) == 0U);
  289. }
  290. CANx_HW_Reset(x);
  291. if (x == 0U) {
  292. LPC_CCU1->CLK_APB3_CAN0_CFG &= ~1U; // Disable C_CAN0 Base Clock
  293. while ((LPC_CCU1->CLK_APB3_CAN0_CFG & 1U) != 0U);
  294. } else {
  295. LPC_CCU1->CLK_APB1_CAN1_CFG &= ~1U; // Disable C_CAN1 Base Clock
  296. while ((LPC_CCU1->CLK_APB1_CAN1_CFG & 1U) != 0U);
  297. }
  298. break;
  299. case ARM_POWER_FULL:
  300. if (can_driver_initialized[x] == 0U) { return ARM_DRIVER_ERROR; }
  301. if (can_driver_powered[x] != 0U) { return ARM_DRIVER_OK; }
  302. if (x == 0U) {
  303. LPC_CGU->BASE_APB3_CLK = (1U << 11) | // Auto-block enable
  304. (9U << 24) ; // Clock source: PLL1
  305. LPC_CCU1->CLK_APB3_CAN0_CFG |= 1U; // Enable C_CAN0 Base Clock
  306. while ((LPC_CCU1->CLK_APB3_CAN0_CFG & 1U) == 0U);
  307. } else {
  308. LPC_CGU->BASE_APB1_CLK = (1U << 11) | // Auto-block enable
  309. (9U << 24) ; // Clock source: PLL1
  310. LPC_CCU1->CLK_APB1_CAN1_CFG |= 1U; // Enable C_CAN1 Base Clock
  311. while ((LPC_CCU1->CLK_APB1_CAN1_CFG & 1U) == 0U);
  312. }
  313. CANx_HW_Reset(x);
  314. can_driver_powered[x] = 1U;
  315. if (x == 0U) {
  316. NVIC_ClearPendingIRQ (C_CAN0_IRQn);
  317. NVIC_EnableIRQ (C_CAN0_IRQn);
  318. } else {
  319. NVIC_ClearPendingIRQ (C_CAN1_IRQn);
  320. NVIC_EnableIRQ (C_CAN1_IRQn);
  321. }
  322. break;
  323. default:
  324. return ARM_DRIVER_ERROR_UNSUPPORTED;
  325. }
  326. return ARM_DRIVER_OK;
  327. }
  328. #if (RTE_CAN_CAN0 == 1U)
  329. static int32_t CAN0_PowerControl (ARM_POWER_STATE state) { return CANx_PowerControl (state, 0U); }
  330. #endif
  331. #if (RTE_CAN_CAN1 == 1U)
  332. static int32_t CAN1_PowerControl (ARM_POWER_STATE state) { return CANx_PowerControl (state, 1U); }
  333. #endif
  334. /**
  335. \fn uint32_t CAN_GetClock (void)
  336. \brief Retrieve CAN base clock frequency.
  337. \return base clock frequency
  338. */
  339. uint32_t CAN_GetClock (void) {
  340. return GetClockFreq(9U);
  341. }
  342. /**
  343. \fn int32_t CANx_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments, uint8_t x)
  344. \brief Set bitrate for CAN interface.
  345. \param[in] select Bitrate selection
  346. - ARM_CAN_BITRATE_NOMINAL : nominal (flexible data-rate arbitration) bitrate
  347. - ARM_CAN_BITRATE_FD_DATA : flexible data-rate data bitrate
  348. \param[in] bitrate Bitrate
  349. \param[in] bit_segments Bit segments settings
  350. \param[in] x Controller number (0..1)
  351. \return execution status
  352. */
  353. static int32_t CANx_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments, uint8_t x) {
  354. LPC_C_CANn_Type *ptr_CAN;
  355. uint32_t cntl, clkdiv, sjw, prop_seg, phase_seg1, phase_seg2, pclk, brp, tq_num;
  356. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  357. if (select != ARM_CAN_BITRATE_NOMINAL) { return ARM_CAN_INVALID_BITRATE_SELECT; }
  358. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  359. prop_seg = (bit_segments & ARM_CAN_BIT_PROP_SEG_Msk ) >> ARM_CAN_BIT_PROP_SEG_Pos;
  360. phase_seg1 = (bit_segments & ARM_CAN_BIT_PHASE_SEG1_Msk) >> ARM_CAN_BIT_PHASE_SEG1_Pos;
  361. phase_seg2 = (bit_segments & ARM_CAN_BIT_PHASE_SEG2_Msk) >> ARM_CAN_BIT_PHASE_SEG2_Pos;
  362. sjw = (bit_segments & ARM_CAN_BIT_SJW_Msk ) >> ARM_CAN_BIT_SJW_Pos;
  363. if (((prop_seg + phase_seg1) < 2U) || ((prop_seg + phase_seg1) > 16U)) { return ARM_CAN_INVALID_BIT_PROP_SEG; }
  364. if (( phase_seg2 < 1U) || ( phase_seg2 > 8U)) { return ARM_CAN_INVALID_BIT_PHASE_SEG2; }
  365. if (( sjw < 1U) || ( sjw > 4U)) { return ARM_CAN_INVALID_BIT_SJW; }
  366. ptr_CAN = ptr_CANx[x];
  367. tq_num = 1U + prop_seg + phase_seg1 + phase_seg2;
  368. pclk = GetClockFreq(9U);
  369. clkdiv = 1U;
  370. while (1U) {
  371. if (clkdiv == 16U) { return ARM_DRIVER_ERROR; }
  372. if (((pclk / clkdiv) <= 50000000U) && (((pclk / clkdiv) % (tq_num * bitrate)) == 0U)) { break; }
  373. clkdiv++;
  374. }
  375. brp = pclk / (tq_num * bitrate * clkdiv);
  376. if (brp > 1024U) { return ARM_CAN_INVALID_BITRATE; }
  377. if (pclk >= (brp * tq_num * bitrate * clkdiv)) {
  378. if (((pclk - (brp * tq_num * bitrate * clkdiv)) * 1024U) > CAN_CLOCK_TOLERANCE) { return ARM_CAN_INVALID_BITRATE; }
  379. } else {
  380. if ((((brp * tq_num * bitrate * clkdiv) - pclk) * 1024U) > CAN_CLOCK_TOLERANCE) { return ARM_CAN_INVALID_BITRATE; }
  381. }
  382. cntl = ptr_CAN->CNTL;
  383. if ((cntl & (CNTL_CCE_Msk | CNTL_INIT_Msk)) != (CNTL_CCE_Msk | CNTL_INIT_Msk)) {
  384. ptr_CAN->CNTL = CNTL_CCE_Msk | // Configuration change enable
  385. CNTL_INIT_Msk ; // Initialization
  386. }
  387. ptr_CAN->BT = ((brp - 1U) & BT_BRP_Msk) | ((sjw - 1U) << 6) | (((prop_seg + phase_seg1) - 1U) << 8) | ((phase_seg2 - 1U) << 12);
  388. ptr_CAN->BRPE = ((brp - 1U) >> 6);
  389. ptr_CAN->CLKDIV = clkdiv - 1U;
  390. ptr_CAN->CNTL = cntl;
  391. return ARM_DRIVER_OK;
  392. }
  393. #if (RTE_CAN_CAN0 == 1U)
  394. static int32_t CAN0_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) { return CANx_SetBitrate (select, bitrate, bit_segments, 0U); }
  395. #endif
  396. #if (RTE_CAN_CAN1 == 1U)
  397. static int32_t CAN1_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) { return CANx_SetBitrate (select, bitrate, bit_segments, 1U); }
  398. #endif
  399. /**
  400. \fn int32_t CANx_SetMode (ARM_CAN_MODE mode, uint8_t x)
  401. \brief Set operating mode for CAN interface.
  402. \param[in] mode Operating mode
  403. - ARM_CAN_MODE_INITIALIZATION : initialization mode
  404. - ARM_CAN_MODE_NORMAL : normal operation mode
  405. - ARM_CAN_MODE_RESTRICTED : restricted operation mode
  406. - ARM_CAN_MODE_MONITOR : bus monitoring mode
  407. - ARM_CAN_MODE_LOOPBACK_INTERNAL : loopback internal mode
  408. - ARM_CAN_MODE_LOOPBACK_EXTERNAL : loopback external mode
  409. \param[in] x Controller number (0..1)
  410. \return execution status
  411. */
  412. static int32_t CANx_SetMode (ARM_CAN_MODE mode, uint8_t x) {
  413. LPC_C_CANn_Type *ptr_CAN;
  414. uint32_t event;
  415. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  416. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  417. ptr_CAN = ptr_CANx[x];
  418. event = 0U;
  419. switch (mode) {
  420. case ARM_CAN_MODE_INITIALIZATION:
  421. ptr_CAN->CNTL = CNTL_INIT_Msk;
  422. event = ARM_CAN_EVENT_UNIT_BUS_OFF;
  423. break;
  424. case ARM_CAN_MODE_NORMAL:
  425. ptr_CAN->CNTL = CNTL_IE_Msk;
  426. if (CAN_SignalUnitEvent[x] != NULL) { ptr_CAN->CNTL |= CNTL_SIE_Msk | CNTL_EIE_Msk; }
  427. event = ARM_CAN_EVENT_UNIT_ACTIVE;
  428. break;
  429. case ARM_CAN_MODE_RESTRICTED:
  430. return ARM_DRIVER_ERROR_UNSUPPORTED;
  431. case ARM_CAN_MODE_MONITOR:
  432. ptr_CAN->CNTL = CNTL_IE_Msk | CNTL_TEST_Msk;
  433. if (CAN_SignalUnitEvent[x] != NULL) { ptr_CAN->CNTL |= CNTL_SIE_Msk | CNTL_EIE_Msk; }
  434. ptr_CAN->TEST = TEST_SILENT_Msk;
  435. event = ARM_CAN_EVENT_UNIT_PASSIVE;
  436. break;
  437. case ARM_CAN_MODE_LOOPBACK_INTERNAL:
  438. ptr_CAN->CNTL = CNTL_IE_Msk | CNTL_TEST_Msk;
  439. if (CAN_SignalUnitEvent[x] != NULL) { ptr_CAN->CNTL |= CNTL_SIE_Msk | CNTL_EIE_Msk; }
  440. ptr_CAN->TEST = TEST_LBACK_Msk | TEST_SILENT_Msk;
  441. event = ARM_CAN_EVENT_UNIT_PASSIVE;
  442. break;
  443. case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
  444. ptr_CAN->CNTL = CNTL_IE_Msk | CNTL_TEST_Msk;
  445. if (CAN_SignalUnitEvent[x] != NULL) { ptr_CAN->CNTL |= CNTL_SIE_Msk | CNTL_EIE_Msk; }
  446. ptr_CAN->TEST = TEST_LBACK_Msk;
  447. event = ARM_CAN_EVENT_UNIT_ACTIVE;
  448. break;
  449. default:
  450. return ARM_DRIVER_ERROR_PARAMETER;
  451. }
  452. if ((CAN_SignalUnitEvent[x] != NULL) && (event != 0U)) { CAN_SignalUnitEvent[x](event); }
  453. return ARM_DRIVER_OK;
  454. }
  455. #if (RTE_CAN_CAN0 == 1U)
  456. static int32_t CAN0_SetMode (ARM_CAN_MODE mode) { return CANx_SetMode (mode, 0U); }
  457. #endif
  458. #if (RTE_CAN_CAN1 == 1U)
  459. static int32_t CAN1_SetMode (ARM_CAN_MODE mode) { return CANx_SetMode (mode, 1U); }
  460. #endif
  461. /**
  462. \fn ARM_CAN_OBJ_CAPABILITIES CANx_ObjectGetCapabilities (uint32_t obj_idx, uint8_t x)
  463. \brief Retrieve capabilities of an object.
  464. \param[in] obj_idx Object index
  465. \param[in] x Controller number (0..1)
  466. \return ARM_CAN_OBJ_CAPABILITIES
  467. */
  468. ARM_CAN_OBJ_CAPABILITIES CANx_ObjectGetCapabilities (uint32_t obj_idx, uint8_t x) {
  469. ARM_CAN_OBJ_CAPABILITIES obj_cap_null;
  470. if ((x >= CAN_CTRL_NUM) || (obj_idx >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM))) {
  471. memset (&obj_cap_null, 0U, sizeof(ARM_CAN_OBJ_CAPABILITIES));
  472. return obj_cap_null;
  473. }
  474. return can_object_capabilities;
  475. }
  476. #if (RTE_CAN_CAN0 == 1U)
  477. ARM_CAN_OBJ_CAPABILITIES CAN0_ObjectGetCapabilities (uint32_t obj_idx) { return CANx_ObjectGetCapabilities (obj_idx, 0U); }
  478. #endif
  479. #if (RTE_CAN_CAN1 == 1U)
  480. ARM_CAN_OBJ_CAPABILITIES CAN1_ObjectGetCapabilities (uint32_t obj_idx) { return CANx_ObjectGetCapabilities (obj_idx, 1U); }
  481. #endif
  482. /**
  483. \fn int32_t CANx_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg, uint8_t x)
  484. \brief Add or remove filter for message reception.
  485. \param[in] obj_idx Object index of object that filter should be or is assigned to
  486. \param[in] operation Operation on filter
  487. - ARM_CAN_FILTER_ID_EXACT_ADD : add exact id filter
  488. - ARM_CAN_FILTER_ID_EXACT_REMOVE : remove exact id filter
  489. - ARM_CAN_FILTER_ID_RANGE_ADD : add range id filter
  490. - ARM_CAN_FILTER_ID_RANGE_REMOVE : remove range id filter
  491. - ARM_CAN_FILTER_ID_MASKABLE_ADD : add maskable id filter
  492. - ARM_CAN_FILTER_ID_MASKABLE_REMOVE : remove maskable id filter
  493. \param[in] id ID or start of ID range (depending on filter type)
  494. \param[in] arg Mask or end of ID range (depending on filter type)
  495. \param[in] x Controller number (0..1)
  496. \return execution status
  497. */
  498. static int32_t CANx_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg, uint8_t x) {
  499. LPC_C_CANn_Type *ptr_CAN;
  500. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  501. if (obj_idx >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM)) { return ARM_DRIVER_ERROR_PARAMETER; }
  502. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  503. ptr_CAN = ptr_CANx[x];
  504. if ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U) { return ARM_DRIVER_ERROR_BUSY; }
  505. ptr_CAN->IF1_CMDMSK_R = // Read
  506. IF_CMDMSK_ARB_Msk ; // Access arbitration
  507. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Read from message object
  508. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for read to finish
  509. // If arbitration in non-zero means filter is already set
  510. switch (operation) {
  511. case ARM_CAN_FILTER_ID_EXACT_ADD:
  512. case ARM_CAN_FILTER_ID_MASKABLE_ADD:
  513. if ((ptr_CAN->IF1_ARB1 != 0U) || (ptr_CAN->IF1_ARB2 != 0U)) { return ARM_DRIVER_ERROR; }
  514. break;
  515. case ARM_CAN_FILTER_ID_EXACT_REMOVE:
  516. case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:
  517. if ((ptr_CAN->IF1_ARB1 == 0U) && (ptr_CAN->IF1_ARB2 == 0U)) { return ARM_DRIVER_OK; }
  518. break;
  519. case ARM_CAN_FILTER_ID_RANGE_ADD:
  520. case ARM_CAN_FILTER_ID_RANGE_REMOVE:
  521. default:
  522. return ARM_DRIVER_ERROR_UNSUPPORTED;
  523. }
  524. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_WR_RD_Msk | // Write
  525. IF_CMDMSK_ARB_Msk ; // Access arbitration
  526. ptr_CAN->IF1_ARB2 = 0U; // Invalidate message object (MSGVAL = 0)
  527. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Write to message object
  528. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for write to finish
  529. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_WR_RD_Msk | // Write
  530. IF_CMDMSK_MASK_Msk | // Access mask
  531. IF_CMDMSK_ARB_Msk | // Access arbitration
  532. IF_CMDMSK_CTRL_Msk ; // Access control bits
  533. switch (operation) {
  534. case ARM_CAN_FILTER_ID_EXACT_ADD:
  535. if ((id & ARM_CAN_ID_IDE_Msk) != 0U) { // Extended Identifier
  536. ptr_CAN->IF1_MSK1 = 0xFFFFU;
  537. ptr_CAN->IF1_MSK2 = 0xBFFFU;
  538. ptr_CAN->IF1_ARB1 = id & IF_ARB1_ID15_0_Msk;
  539. ptr_CAN->IF1_ARB2 = ((id >> 16) & IF_ARB2_ID28_16_Msk) | IF_ARB2_XTD_Msk;
  540. } else { // Standard Identifier
  541. ptr_CAN->IF1_MSK1 = 0U;
  542. ptr_CAN->IF1_MSK2 = 0xBFFCU;
  543. ptr_CAN->IF1_ARB1 = 0U;
  544. ptr_CAN->IF1_ARB2 = (id << 2) & IF_ARB2_ID28_16_Msk;
  545. }
  546. break;
  547. case ARM_CAN_FILTER_ID_MASKABLE_ADD:
  548. if ((id & ARM_CAN_ID_IDE_Msk) != 0U) { // Extended Identifier
  549. ptr_CAN->IF1_MSK1 = arg & IF_MSK1_MSK15_0_Msk;
  550. ptr_CAN->IF1_MSK2 = ((arg >> 16) & IF_MSK2_MSK28_16_Msk) | IF_MSK2_MXTD_Msk;
  551. ptr_CAN->IF1_ARB1 = id & IF_ARB1_ID15_0_Msk;
  552. ptr_CAN->IF1_ARB2 = ((id >> 16) & IF_ARB2_ID28_16_Msk) | IF_ARB2_XTD_Msk;
  553. } else { // Standard Identifier
  554. ptr_CAN->IF1_MSK1 = 0U;
  555. ptr_CAN->IF1_MSK2 = ((arg << 2) & IF_MSK2_MSK28_16_Msk) | IF_MSK2_MXTD_Msk;
  556. ptr_CAN->IF1_ARB1 = 0U;
  557. ptr_CAN->IF1_ARB2 = (id << 2) & IF_ARB2_ID28_16_Msk;
  558. }
  559. break;
  560. case ARM_CAN_FILTER_ID_EXACT_REMOVE:
  561. case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:
  562. ptr_CAN->IF1_MSK1 = 0U;
  563. ptr_CAN->IF1_MSK2 = 0U;
  564. ptr_CAN->IF1_ARB1 = 0U;
  565. ptr_CAN->IF1_ARB2 = 0U;
  566. break;
  567. case ARM_CAN_FILTER_ID_RANGE_ADD:
  568. case ARM_CAN_FILTER_ID_RANGE_REMOVE:
  569. default:
  570. return ARM_DRIVER_ERROR_UNSUPPORTED;
  571. }
  572. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Write to message object
  573. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for write to finish
  574. return ARM_DRIVER_OK;
  575. }
  576. #if (RTE_CAN_CAN0 == 1U)
  577. static int32_t CAN0_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) { return CANx_ObjectSetFilter (obj_idx, operation, id, arg, 0U); }
  578. #endif
  579. #if (RTE_CAN_CAN1 == 1U)
  580. static int32_t CAN1_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) { return CANx_ObjectSetFilter (obj_idx, operation, id, arg, 1U); }
  581. #endif
  582. /**
  583. \fn int32_t CANx_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg, uint8_t x)
  584. \brief Configure object.
  585. \param[in] obj_idx Object index
  586. \param[in] obj_cfg Object configuration state
  587. - ARM_CAN_OBJ_INACTIVE : deactivate object
  588. - ARM_CAN_OBJ_RX : configure object for reception
  589. - ARM_CAN_OBJ_TX : configure object for transmission
  590. - ARM_CAN_OBJ_RX_RTR_TX_DATA : configure object that on RTR reception automatically transmits Data Frame
  591. - ARM_CAN_OBJ_TX_RTR_RX_DATA : configure object that transmits RTR and automatically receives Data Frame
  592. \param[in] x Controller number (0..1)
  593. \return execution status
  594. */
  595. static int32_t CANx_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg, uint8_t x) {
  596. LPC_C_CANn_Type *ptr_CAN;
  597. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  598. if (obj_idx >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM)) { return ARM_DRIVER_ERROR_PARAMETER; }
  599. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  600. ptr_CAN = ptr_CANx[x];
  601. if ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U) { return ARM_DRIVER_ERROR_BUSY; }
  602. ptr_CAN->IF1_CMDMSK_R = // Read
  603. IF_CMDMSK_MASK_Msk | // Access mask
  604. IF_CMDMSK_ARB_Msk | // Access arbitration
  605. IF_CMDMSK_CTRL_Msk ; // Access control bits
  606. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Write to message object
  607. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for read to finish
  608. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_WR_RD_Msk | // Write
  609. IF_CMDMSK_MASK_Msk | // Access mask
  610. IF_CMDMSK_ARB_Msk | // Access arbitration
  611. IF_CMDMSK_CTRL_Msk ; // Access control bits
  612. switch (obj_cfg) {
  613. case ARM_CAN_OBJ_INACTIVE:
  614. ptr_CAN->IF1_ARB2 = 0U; // Invalidate message object (MSGVAL = 0)
  615. ptr_CAN->IF1_MCTRL = 0U; // Clear control register
  616. break;
  617. case ARM_CAN_OBJ_TX:
  618. ptr_CAN->IF1_MSK2 |= IF_MSK2_MDIR_Msk ; // Use DIR for acceptance filtering
  619. ptr_CAN->IF1_ARB2 |= IF_ARB2_DIR_Msk | // Tx object
  620. IF_ARB2_MSGVAL_Msk ; // Message is Valid
  621. ptr_CAN->IF1_MCTRL = IF_MCTRL_EOB_Msk | // End of Buffer
  622. IF_MCTRL_TXIE_Msk ; // Tx Interrupt Enable
  623. break;
  624. case ARM_CAN_OBJ_RX:
  625. ptr_CAN->IF1_MSK2 |= IF_MSK2_MDIR_Msk ; // Use DIR for acceptance filtering
  626. ptr_CAN->IF1_ARB2 &= ~IF_ARB2_DIR_Msk ; // Rx object
  627. ptr_CAN->IF1_ARB2 |= IF_ARB2_MSGVAL_Msk ; // Message is Valid
  628. ptr_CAN->IF1_MCTRL = IF_MCTRL_UMASK_Msk | // Use mask for acceptance filtering
  629. IF_MCTRL_EOB_Msk | // End of Buffer
  630. IF_MCTRL_RXIE_Msk | // Rx Interrupt Enable
  631. 8U ; // Receive 8 bytes
  632. break;
  633. case ARM_CAN_OBJ_RX_RTR_TX_DATA:
  634. ptr_CAN->IF1_MSK2 &= ~IF_MSK2_MDIR_Msk ; // Do not use DIR for acceptance filtering
  635. ptr_CAN->IF1_ARB2 |= IF_ARB2_DIR_Msk | // Tx object
  636. IF_ARB2_MSGVAL_Msk ; // Message is Valid
  637. ptr_CAN->IF1_MCTRL = IF_MCTRL_UMASK_Msk | // Use mask for acceptance filtering
  638. IF_MCTRL_EOB_Msk | // End of Buffer
  639. IF_MCTRL_TXIE_Msk | // Tx Interrupt Enable
  640. IF_MCTRL_RMTEN_Msk ; // Remote Enable
  641. break;
  642. case ARM_CAN_OBJ_TX_RTR_RX_DATA:
  643. ptr_CAN->IF1_MSK2 &= ~IF_MSK2_MDIR_Msk ; // Do not use DIR for acceptance filtering
  644. ptr_CAN->IF1_ARB2 &= ~IF_ARB2_DIR_Msk ; // Rx object
  645. ptr_CAN->IF1_ARB2 |= IF_ARB2_MSGVAL_Msk ; // Message is Valid
  646. ptr_CAN->IF1_MCTRL = IF_MCTRL_UMASK_Msk | // Use mask for acceptance filtering
  647. IF_MCTRL_EOB_Msk | // End of Buffer
  648. IF_MCTRL_RXIE_Msk ; // Rx Interrupt Enable
  649. break;
  650. default:
  651. return ARM_DRIVER_ERROR;
  652. }
  653. can_obj_cfg[x][obj_idx] = obj_cfg;
  654. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Write to message object
  655. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for write to finish
  656. return ARM_DRIVER_OK;
  657. }
  658. #if (RTE_CAN_CAN0 == 1U)
  659. static int32_t CAN0_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) { return CANx_ObjectConfigure (obj_idx, obj_cfg, 0U); }
  660. #endif
  661. #if (RTE_CAN_CAN1 == 1U)
  662. static int32_t CAN1_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) { return CANx_ObjectConfigure (obj_idx, obj_cfg, 1U); }
  663. #endif
  664. /**
  665. \fn int32_t CANx_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size, uint8_t x)
  666. \brief Send message on CAN bus.
  667. \param[in] obj_idx Object index
  668. \param[in] msg_info Pointer to CAN message information
  669. \param[in] data Pointer to data buffer
  670. \param[in] size Number of data bytes to send
  671. \param[in] x Controller number (0..1)
  672. \return value >= 0 number of data bytes accepted to send
  673. \return value < 0 execution status
  674. */
  675. static int32_t CANx_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size, uint8_t x) {
  676. LPC_C_CANn_Type *ptr_CAN;
  677. uint32_t arb1, arb2, mctrl;
  678. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  679. if (obj_idx >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM)) { return ARM_DRIVER_ERROR_PARAMETER; }
  680. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  681. if (can_obj_cfg[x][obj_idx] == ARM_CAN_OBJ_RX) { return ARM_DRIVER_ERROR; }
  682. ptr_CAN = ptr_CANx[x];
  683. if ((((ptr_CAN->TXREQ2 << 16) | (ptr_CAN->TXREQ1 & 0xFFFFU)) & (1U << obj_idx)) != 0U) {
  684. return ARM_DRIVER_ERROR_BUSY;
  685. }
  686. if ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U) { return ARM_DRIVER_ERROR_BUSY; }
  687. ptr_CAN->IF1_CMDMSK_R = // Read
  688. IF_CMDMSK_ARB_Msk | // Access arbitration
  689. IF_CMDMSK_CTRL_Msk | // Access control bits
  690. IF_CMDMSK_NEWDAT_Msk; // Clear NEWDAT bit
  691. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Read from message object
  692. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for read to finish
  693. mctrl = ptr_CAN->IF1_MCTRL; // Store current value of MCTRL register
  694. arb1 = ptr_CAN->IF1_ARB1; // Store current value of ARB1 register
  695. arb2 = ptr_CAN->IF1_ARB2; // Store current value of ARB2 register
  696. // Prepare arb1..2
  697. if (can_obj_cfg[x][obj_idx] == ARM_CAN_OBJ_TX) { // For Tx object id is prepared here
  698. if (msg_info->id & ARM_CAN_ID_IDE_Msk) { // Extended Identifier
  699. arb1 = msg_info->id & IF_ARB1_ID15_0_Msk;
  700. arb2 = ((msg_info->id >> 16) & IF_ARB2_ID28_16_Msk) | IF_ARB2_XTD_Msk | IF_ARB2_MSGVAL_Msk;
  701. } else { // Standard Identifier
  702. arb1 = 0U;
  703. arb2 = ((msg_info->id << 2) & IF_ARB2_ID28_16_Msk) | IF_ARB2_MSGVAL_Msk;
  704. }
  705. }
  706. switch (can_obj_cfg[x][obj_idx]) {
  707. case ARM_CAN_OBJ_INACTIVE:
  708. case ARM_CAN_OBJ_RX:
  709. return ARM_DRIVER_ERROR;
  710. case ARM_CAN_OBJ_TX:
  711. if (msg_info->rtr == 0U) { // If Data frame transmit requested
  712. arb2 |= IF_ARB2_DIR_Msk; // Tx object
  713. } else { // else if Remote Transmission Request frame transmit requested
  714. size = msg_info->dlc; // Prepare number of data bytes to request
  715. }
  716. if (size > 8U) { size = 8U; }
  717. mctrl = (mctrl & ~0xFU) |
  718. IF_MCTRL_TXRQST_Msk | // Set Tx Request
  719. size ; // Number of bytes to transmit or requested by RTR
  720. break;
  721. case ARM_CAN_OBJ_RX_RTR_TX_DATA:
  722. mctrl = (mctrl & ~0xFU) |
  723. size ; // Number of bytes to transmit or requested by RTR
  724. break;
  725. case ARM_CAN_OBJ_TX_RTR_RX_DATA:
  726. if (msg_info->rtr) { // If Remote Transmission Request frame transmit requested
  727. size = msg_info->dlc; // Prepare number of data bytes to request
  728. }
  729. if (size > 8U) { size = 8U; }
  730. mctrl = (mctrl & ~0xFU) |
  731. IF_MCTRL_TXRQST_Msk | // Set Tx Request
  732. size ; // Number of bytes requested by RTR
  733. break;
  734. default:
  735. return ARM_DRIVER_ERROR;
  736. } // Store object type information
  737. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_WR_RD_Msk | // Write
  738. IF_CMDMSK_ARB_Msk | // Access arbitration
  739. IF_CMDMSK_CTRL_Msk ; // Access control bits
  740. ptr_CAN->IF1_ARB1 = arb1;
  741. ptr_CAN->IF1_ARB2 = arb2;
  742. ptr_CAN->IF1_MCTRL = mctrl;
  743. if (can_obj_cfg[x][obj_idx] != ARM_CAN_OBJ_TX_RTR_RX_DATA) {
  744. ptr_CAN->IF1_DA1 = (((uint16_t)(data[1])) << 8) | data[0];
  745. ptr_CAN->IF1_DA2 = (((uint16_t)(data[3])) << 8) | data[2];
  746. ptr_CAN->IF1_CMDMSK_W |= IF_CMDMSK_DATA_A_Msk; // Access data bytes 0..3
  747. if (size > 4) {
  748. ptr_CAN->IF1_DB1 = (((uint16_t)(data[5])) << 8) | data[4];
  749. ptr_CAN->IF1_DB2 = (((uint16_t)(data[7])) << 8) | data[6];
  750. ptr_CAN->IF1_CMDMSK_W |= IF_CMDMSK_DATA_B_Msk; // Access data bytes 4..7
  751. }
  752. }
  753. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Write to message object
  754. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for write to finish
  755. return ((int32_t)size);
  756. }
  757. #if (RTE_CAN_CAN0 == 1U)
  758. static int32_t CAN0_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) { return CANx_MessageSend (obj_idx, msg_info, data, size, 0U); }
  759. #endif
  760. #if (RTE_CAN_CAN1 == 1U)
  761. static int32_t CAN1_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) { return CANx_MessageSend (obj_idx, msg_info, data, size, 1U); }
  762. #endif
  763. /**
  764. \fn int32_t CANx_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size, uint8_t x)
  765. \brief Read message received on CAN bus.
  766. \param[in] obj_idx Object index
  767. \param[out] msg_info Pointer to read CAN message information
  768. \param[out] data Pointer to data buffer for read data
  769. \param[in] size Maximum number of data bytes to read
  770. \param[in] x Controller number (0..1)
  771. \return value >= 0 number of data bytes read
  772. \return value < 0 execution status
  773. */
  774. static int32_t CANx_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size, uint8_t x) {
  775. LPC_C_CANn_Type *ptr_CAN;
  776. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  777. if (obj_idx >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM)) { return ARM_DRIVER_ERROR_PARAMETER; }
  778. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  779. if (can_obj_cfg[x][obj_idx] == ARM_CAN_OBJ_TX) { return ARM_DRIVER_ERROR; }
  780. if (can_obj_cfg[x][obj_idx] == ARM_CAN_OBJ_RX_RTR_TX_DATA) { return ARM_DRIVER_ERROR; }
  781. ptr_CAN = ptr_CANx[x];
  782. if (size > 8U) { size = 8U; }
  783. ptr_CAN->IF1_CMDMSK_R = // Read
  784. IF_CMDMSK_ARB_Msk | // Access arbitration
  785. IF_CMDMSK_CTRL_Msk | // Access control bits
  786. IF_CMDMSK_NEWDAT_Msk | // Access New Data bit (clear it)
  787. IF_CMDMSK_DATA_B_Msk | // Access data bytes 4..7
  788. IF_CMDMSK_DATA_A_Msk ; // Access data bytes 0..3
  789. ptr_CAN->IF1_CMDREQ = obj_idx + 1U; // Read from message object
  790. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for read to finish
  791. if ((ptr_CAN->IF1_ARB2 & IF_ARB2_XTD_Msk) != 0U) { // Extended Identifier
  792. msg_info->id = (0x1FFFFFFFU & (((ptr_CAN->IF1_ARB2 & IF_ARB2_ID28_16_Msk) << 16) | (ptr_CAN->IF1_ARB1 & IF_ARB1_ID15_0_Msk))) | ARM_CAN_ID_IDE_Msk;
  793. } else { // Standard Identifier
  794. msg_info->id = (0x000007FFU & ((ptr_CAN->IF1_ARB2 & IF_ARB2_ID28_16_Msk) >> 2));
  795. }
  796. msg_info->rtr = 0U;
  797. msg_info->dlc = ptr_CAN->IF1_MCTRL & IF_MCTRL_DLC3_0_Msk;
  798. if (size > msg_info->dlc) { size = msg_info->dlc; }
  799. if (size > 0U) { data[0] = (ptr_CAN->IF1_DA1);
  800. if (size > 1U) { data[1] = (ptr_CAN->IF1_DA1 >> 8);
  801. if (size > 2U) { data[2] = (ptr_CAN->IF1_DA2);
  802. if (size > 3U) { data[3] = (ptr_CAN->IF1_DA2 >> 8);
  803. if (size > 4U) { data[4] = (ptr_CAN->IF1_DB1);
  804. if (size > 5U) { data[5] = (ptr_CAN->IF1_DB1 >> 8);
  805. if (size > 6U) { data[6] = (ptr_CAN->IF1_DB2);
  806. if (size > 7U) { data[7] = (ptr_CAN->IF1_DB2 >> 8); }
  807. }
  808. }
  809. }
  810. }
  811. }
  812. }
  813. }
  814. if (ptr_CAN->IF1_MCTRL & IF_MCTRL_MSGLST_Msk) {
  815. // If message was lost (MSGLST=1), clear this bit for new reception as now
  816. // the message was read-out and is free for new reception
  817. ptr_CAN->IF1_MCTRL &= ~(IF_MCTRL_MSGLST_Msk | IF_MCTRL_NEWDAT_Msk | IF_MCTRL_INTPND_Msk);
  818. ptr_CAN->IF1_CMDMSK_W = IF_CMDMSK_CTRL_Msk |
  819. IF_CMDMSK_WR_RD_Msk;
  820. ptr_CAN->IF1_CMDREQ = obj_idx + 1U;
  821. while ((ptr_CAN->IF1_CMDREQ&IF_CMDREQ_BUSY_Msk)!=0U); // Wait for read to finish
  822. }
  823. return ((int32_t)size);
  824. }
  825. #if (RTE_CAN_CAN0 == 1U)
  826. static int32_t CAN0_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) { return CANx_MessageRead (obj_idx, msg_info, data, size, 0U); }
  827. #endif
  828. #if (RTE_CAN_CAN1 == 1U)
  829. static int32_t CAN1_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) { return CANx_MessageRead (obj_idx, msg_info, data, size, 1U); }
  830. #endif
  831. /**
  832. \fn int32_t CANx_Control (uint32_t control, uint32_t arg, uint8_t x)
  833. \brief Control CAN interface.
  834. \param[in] control Operation
  835. - ARM_CAN_SET_FD_MODE : set FD operation mode
  836. - ARM_CAN_ABORT_MESSAGE_SEND : abort sending of CAN message
  837. - ARM_CAN_CONTROL_RETRANSMISSION : enable/disable automatic retransmission
  838. - ARM_CAN_SET_TRANSCEIVER_DELAY : set transceiver delay
  839. \param[in] arg Argument of operation
  840. \param[in] x Controller number (0..1)
  841. \return execution status
  842. */
  843. static int32_t CANx_Control (uint32_t control, uint32_t arg, uint8_t x) {
  844. LPC_C_CANn_Type *ptr_CAN;
  845. if (x >= CAN_CTRL_NUM) { return ARM_DRIVER_ERROR; }
  846. if (can_driver_powered[x] == 0U) { return ARM_DRIVER_ERROR; }
  847. ptr_CAN = ptr_CANx[x];
  848. switch (control & ARM_CAN_CONTROL_Msk) {
  849. case ARM_CAN_ABORT_MESSAGE_SEND:
  850. if (arg >= ((x) ? CAN1_OBJ_NUM : CAN0_OBJ_NUM)) { return ARM_DRIVER_ERROR_PARAMETER; }
  851. if (can_obj_cfg[x][arg] != ARM_CAN_OBJ_TX) { return ARM_DRIVER_ERROR; }
  852. CANx_AbortSendMessage (arg, x);
  853. break;
  854. case ARM_CAN_CONTROL_RETRANSMISSION:
  855. switch (arg) {
  856. case 0:
  857. ptr_CAN->CNTL |= CNTL_DAR_Msk; // Disable automatic retransmission
  858. break;
  859. case 1:
  860. ptr_CAN->CNTL &= ~CNTL_DAR_Msk; // Enable automatic retransmission
  861. break;
  862. default:
  863. return ARM_DRIVER_ERROR_PARAMETER;
  864. }
  865. break;
  866. case ARM_CAN_SET_FD_MODE:
  867. case ARM_CAN_SET_TRANSCEIVER_DELAY:
  868. default:
  869. return ARM_DRIVER_ERROR_UNSUPPORTED;
  870. }
  871. return ARM_DRIVER_OK;
  872. }
  873. #if (RTE_CAN_CAN0 == 1U)
  874. static int32_t CAN0_Control (uint32_t control, uint32_t arg) { return CANx_Control (control, arg, 0U); }
  875. #endif
  876. #if (RTE_CAN_CAN1 == 1U)
  877. static int32_t CAN1_Control (uint32_t control, uint32_t arg) { return CANx_Control (control, arg, 1U); }
  878. #endif
  879. /**
  880. \fn ARM_CAN_STATUS CANx_GetStatus (uint8_t x)
  881. \brief Get CAN status.
  882. \param[in] x Controller number (0..1)
  883. \return CAN status ARM_CAN_STATUS
  884. */
  885. static ARM_CAN_STATUS CANx_GetStatus (uint8_t x) {
  886. LPC_C_CANn_Type *ptr_CAN;
  887. ARM_CAN_STATUS can_status;
  888. uint32_t stat, ec;
  889. if ((x >= CAN_CTRL_NUM) || (can_driver_powered[x] == 0U)) {
  890. memset(&can_status, 0U, sizeof(ARM_CAN_STATUS));
  891. return can_status;
  892. }
  893. ptr_CAN = ptr_CANx[x];
  894. stat = ptr_CAN->STAT;
  895. ec = ptr_CAN->EC;
  896. if ((ptr_CAN->CNTL & CNTL_INIT_Msk) != 0U) { can_status.unit_state = ARM_CAN_UNIT_STATE_INACTIVE; }
  897. else if (((ptr_CAN->CNTL & CNTL_TEST_Msk) != 0U) &&
  898. ((ptr_CAN->TEST & TEST_SILENT_Msk) != 0U)) { can_status.unit_state = ARM_CAN_UNIT_STATE_PASSIVE; }
  899. else if ((stat & STAT_BOFF_Msk) != 0U) { can_status.unit_state = ARM_CAN_UNIT_STATE_INACTIVE; }
  900. else if ((stat & STAT_EPASS_Msk) != 0U) { can_status.unit_state = ARM_CAN_UNIT_STATE_PASSIVE; }
  901. else { can_status.unit_state = ARM_CAN_UNIT_STATE_ACTIVE; }
  902. switch (stat & STAT_LEC_Msk) {
  903. case 0:
  904. can_status.last_error_code = ARM_CAN_LEC_NO_ERROR;
  905. break;
  906. case 1:
  907. can_status.last_error_code = ARM_CAN_LEC_STUFF_ERROR;
  908. break;
  909. case 2:
  910. can_status.last_error_code = ARM_CAN_LEC_FORM_ERROR;
  911. break;
  912. case 3:
  913. can_status.last_error_code = ARM_CAN_LEC_ACK_ERROR;
  914. break;
  915. case 4:
  916. case 5:
  917. can_status.last_error_code = ARM_CAN_LEC_BIT_ERROR;
  918. break;
  919. case 6:
  920. can_status.last_error_code = ARM_CAN_LEC_CRC_ERROR;
  921. break;
  922. case 7:
  923. can_status.last_error_code = ARM_CAN_LEC_NO_ERROR;
  924. break;
  925. }
  926. can_status.tx_error_count = (uint8_t)((ec & EC_TEC_7_0_Msk));
  927. if ((ec & EC_RP_Msk) != 0U) {
  928. can_status.rx_error_count = 128U;
  929. } else {
  930. can_status.rx_error_count = (uint8_t)((ec & EC_REC_6_0_Msk) >> 8);
  931. }
  932. return can_status;
  933. }
  934. #if (RTE_CAN_CAN0 == 1U)
  935. static ARM_CAN_STATUS CAN0_GetStatus (void) { return CANx_GetStatus (0U); }
  936. #endif
  937. #if (RTE_CAN_CAN1 == 1U)
  938. static ARM_CAN_STATUS CAN1_GetStatus (void) { return CANx_GetStatus (1U); }
  939. #endif
  940. /**
  941. \fn void CAN0_IRQHandler (void)
  942. \brief CAN0 Interrupt Routine (IRQ).
  943. */
  944. #if (RTE_CAN_CAN0 == 1U)
  945. void CAN0_IRQHandler (void) {
  946. uint32_t obj_idx, stat;
  947. while (1) {
  948. obj_idx = LPC_C_CAN0->INT; if (obj_idx == 0U) { break; }
  949. if (obj_idx && (obj_idx <= 0x20U)) { // Message Object Interrupt
  950. LPC_C_CAN0->IF2_CMDMSK_R = IF_CMDMSK_CTRL_Msk | IF_CMDMSK_CLRINTPND_Msk;
  951. LPC_C_CAN0->IF2_CMDREQ = obj_idx;
  952. while (LPC_C_CAN0->IF2_CMDREQ & IF_CMDREQ_BUSY_Msk);
  953. obj_idx --;
  954. if (CAN_SignalObjectEvent[0] != NULL) {
  955. switch (can_obj_cfg[0][obj_idx]) {
  956. case ARM_CAN_OBJ_INACTIVE:
  957. break;
  958. case ARM_CAN_OBJ_TX:
  959. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_SEND_COMPLETE);
  960. break;
  961. case ARM_CAN_OBJ_RX:
  962. if (LPC_C_CAN0->IF2_MCTRL & IF_MCTRL_MSGLST_Msk) {
  963. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_RECEIVE | ARM_CAN_EVENT_RECEIVE_OVERRUN);
  964. } else {
  965. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_RECEIVE);
  966. }
  967. break;
  968. case ARM_CAN_OBJ_RX_RTR_TX_DATA:
  969. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_SEND_COMPLETE);
  970. break;
  971. case ARM_CAN_OBJ_TX_RTR_RX_DATA:
  972. if (LPC_C_CAN0->IF2_MCTRL & IF_MCTRL_NEWDAT_Msk) {
  973. if (LPC_C_CAN0->IF2_MCTRL & IF_MCTRL_MSGLST_Msk) {
  974. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_RECEIVE | ARM_CAN_EVENT_RECEIVE_OVERRUN);
  975. } else {
  976. CAN_SignalObjectEvent[0](obj_idx, ARM_CAN_EVENT_RECEIVE);
  977. }
  978. }
  979. break;
  980. default:
  981. break;
  982. }
  983. }
  984. } else if (obj_idx == 0x8000U) { // Status interrupt
  985. stat = LPC_C_CAN0->STAT;
  986. if (CAN_SignalUnitEvent[0] != NULL) {
  987. if ((stat ^ can_stat_last[0]) & (STAT_BOFF_Msk | STAT_EPASS_Msk | STAT_EWARN_Msk)) {
  988. if (stat & (stat ^ can_stat_last[0]) & STAT_BOFF_Msk ) { CAN_SignalUnitEvent[0](ARM_CAN_EVENT_UNIT_BUS_OFF); }
  989. else if (stat & (stat ^ can_stat_last[0]) & STAT_EPASS_Msk) { CAN_SignalUnitEvent[0](ARM_CAN_EVENT_UNIT_PASSIVE); }
  990. else if (stat & (stat ^ can_stat_last[0]) & STAT_EWARN_Msk) { CAN_SignalUnitEvent[0](ARM_CAN_EVENT_UNIT_WARNING); }
  991. else if (stat & (STAT_BOFF_Msk | STAT_EPASS_Msk | STAT_EWARN_Msk)) { CAN_SignalUnitEvent[0](ARM_CAN_EVENT_UNIT_ACTIVE); }
  992. }
  993. can_stat_last[0] = stat;
  994. }
  995. }
  996. }
  997. }
  998. #endif
  999. /**
  1000. \fn void CAN1_IRQHandler (void)
  1001. \brief CAN1 Interrupt Routine (IRQ).
  1002. */
  1003. #if (RTE_CAN_CAN1 == 1U)
  1004. void CAN1_IRQHandler (void) {
  1005. uint32_t obj_idx, stat;
  1006. while (1) {
  1007. obj_idx = LPC_C_CAN1->INT; if (obj_idx == 0U) { break; }
  1008. if (obj_idx && (obj_idx <= 0x20U)) { // Message Object Interrupt
  1009. LPC_C_CAN1->IF2_CMDMSK_R = IF_CMDMSK_CTRL_Msk | IF_CMDMSK_CLRINTPND_Msk;
  1010. LPC_C_CAN1->IF2_CMDREQ = obj_idx;
  1011. while (LPC_C_CAN1->IF2_CMDREQ & IF_CMDREQ_BUSY_Msk);
  1012. obj_idx --;
  1013. if (CAN_SignalObjectEvent[1] != NULL) {
  1014. switch (can_obj_cfg[1][obj_idx]) {
  1015. case ARM_CAN_OBJ_INACTIVE:
  1016. break;
  1017. case ARM_CAN_OBJ_TX:
  1018. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_SEND_COMPLETE);
  1019. break;
  1020. case ARM_CAN_OBJ_RX:
  1021. if (LPC_C_CAN1->IF2_MCTRL & IF_MCTRL_MSGLST_Msk) {
  1022. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_RECEIVE | ARM_CAN_EVENT_RECEIVE_OVERRUN);
  1023. } else {
  1024. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_RECEIVE);
  1025. }
  1026. break;
  1027. case ARM_CAN_OBJ_RX_RTR_TX_DATA:
  1028. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_SEND_COMPLETE);
  1029. break;
  1030. case ARM_CAN_OBJ_TX_RTR_RX_DATA:
  1031. if (LPC_C_CAN1->IF2_MCTRL & IF_MCTRL_NEWDAT_Msk) {
  1032. if (LPC_C_CAN1->IF2_MCTRL & IF_MCTRL_MSGLST_Msk) {
  1033. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_RECEIVE | ARM_CAN_EVENT_RECEIVE_OVERRUN);
  1034. } else {
  1035. CAN_SignalObjectEvent[1](obj_idx, ARM_CAN_EVENT_RECEIVE);
  1036. }
  1037. }
  1038. break;
  1039. default:
  1040. break;
  1041. }
  1042. }
  1043. } else if (obj_idx == 0x8000U) { // Status interrupt
  1044. stat = LPC_C_CAN1->STAT;
  1045. if (CAN_SignalUnitEvent[1] != NULL) {
  1046. if ((stat ^ can_stat_last[1]) & (STAT_BOFF_Msk | STAT_EPASS_Msk | STAT_EWARN_Msk)) {
  1047. if (stat & (stat ^ can_stat_last[1]) & STAT_BOFF_Msk ) { CAN_SignalUnitEvent[1](ARM_CAN_EVENT_UNIT_BUS_OFF); }
  1048. else if (stat & (stat ^ can_stat_last[1]) & STAT_EPASS_Msk) { CAN_SignalUnitEvent[1](ARM_CAN_EVENT_UNIT_PASSIVE); }
  1049. else if (stat & (stat ^ can_stat_last[1]) & STAT_EWARN_Msk) { CAN_SignalUnitEvent[1](ARM_CAN_EVENT_UNIT_WARNING); }
  1050. else if (stat & (STAT_BOFF_Msk | STAT_EPASS_Msk | STAT_EWARN_Msk)) { CAN_SignalUnitEvent[1](ARM_CAN_EVENT_UNIT_ACTIVE); }
  1051. can_stat_last[1] = stat;
  1052. }
  1053. }
  1054. }
  1055. }
  1056. }
  1057. #endif
  1058. #if (RTE_CAN_CAN0 == 1U)
  1059. ARM_DRIVER_CAN Driver_CAN0 = {
  1060. CAN_GetVersion,
  1061. CAN0_GetCapabilities,
  1062. CAN0_Initialize,
  1063. CAN0_Uninitialize,
  1064. CAN0_PowerControl,
  1065. CAN_GetClock,
  1066. CAN0_SetBitrate,
  1067. CAN0_SetMode,
  1068. CAN0_ObjectGetCapabilities,
  1069. CAN0_ObjectSetFilter,
  1070. CAN0_ObjectConfigure,
  1071. CAN0_MessageSend,
  1072. CAN0_MessageRead,
  1073. CAN0_Control,
  1074. CAN0_GetStatus
  1075. };
  1076. #endif
  1077. #if (RTE_CAN_CAN1 == 1U)
  1078. ARM_DRIVER_CAN Driver_CAN1 = {
  1079. CAN_GetVersion,
  1080. CAN1_GetCapabilities,
  1081. CAN1_Initialize,
  1082. CAN1_Uninitialize,
  1083. CAN1_PowerControl,
  1084. CAN_GetClock,
  1085. CAN1_SetBitrate,
  1086. CAN1_SetMode,
  1087. CAN1_ObjectGetCapabilities,
  1088. CAN1_ObjectSetFilter,
  1089. CAN1_ObjectConfigure,
  1090. CAN1_MessageSend,
  1091. CAN1_MessageRead,
  1092. CAN1_Control,
  1093. CAN1_GetStatus
  1094. };
  1095. #endif