drv_lpccan.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. /*
  2. * File : drv_lpccan.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2015, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2015-06-30 aubrcool@qq.com first version
  13. */
  14. #include <rthw.h>
  15. #include <rtdevice.h>
  16. #include <board.h>
  17. #include <drv_lpccan.h>
  18. #ifdef RT_USING_COMPONENTS_INIT
  19. #include <components.h>
  20. #endif
  21. #ifdef RT_USING_CAN
  22. #include "lpc_types.h"
  23. #include "lpc_can.h"
  24. #include "lpc_pinsel.h"
  25. #include "lpc_exti.h"
  26. #include "lpc_clkpwr.h"
  27. struct lpccandata
  28. {
  29. en_CAN_unitId id;
  30. };
  31. static LPC_CAN_TypeDef* lcpcan_get_reg_base(rt_uint32_t id)
  32. {
  33. LPC_CAN_TypeDef* pCan;
  34. switch (id)
  35. {
  36. case CAN_ID_1:
  37. pCan = LPC_CAN1;
  38. break;
  39. case CAN_ID_2:
  40. pCan = LPC_CAN2;
  41. break;
  42. default:
  43. pCan = NULL;
  44. }
  45. return pCan;
  46. }
  47. static void lpccan_irqstate_init(rt_uint32_t id)
  48. {
  49. LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id);
  50. volatile rt_int32_t i;
  51. pCan->MOD = 1; // Enter Reset Mode
  52. pCan->IER = 0; // Disable All CAN Interrupts
  53. pCan->GSR = 0;
  54. /* Request command to release Rx, Tx buffer and clear data overrun */
  55. //pCan->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
  56. pCan->CMR = (1 << 1) | (1 << 2) | (1 << 3);
  57. /* Read to clear interrupt pending in interrupt capture register */
  58. i = pCan->ICR;
  59. i = i;
  60. pCan->MOD = 0;// Return Normal operating
  61. }
  62. static rt_err_t lpccan_baud_set(rt_uint32_t id, rt_uint32_t baud)
  63. {
  64. uint32_t result = 0;
  65. uint8_t NT, TSEG1, TSEG2;
  66. uint32_t CANPclk = 0;
  67. uint32_t BRP;
  68. LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id);
  69. CANPclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER);
  70. result = CANPclk / baud;
  71. /* Calculate suitable nominal time value
  72. * NT (nominal time) = (TSEG1 + TSEG2 + 3)
  73. * NT <= 24
  74. * TSEG1 >= 2*TSEG2
  75. */
  76. for(NT = 24; NT > 0; NT = NT-2)
  77. {
  78. if ((result % NT) == 0)
  79. {
  80. BRP = result / NT - 1;
  81. NT--;
  82. TSEG2 = (NT/3) - 1;
  83. TSEG1 = NT -(NT/3) - 1;
  84. break;
  85. }
  86. }
  87. /* Enter reset mode */
  88. pCan->MOD = 0x01;
  89. /* Set bit timing
  90. * Default: SAM = 0x00;
  91. * SJW = 0x03;
  92. */
  93. pCan->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP;
  94. /* Return to normal operating */
  95. pCan->MOD = 0;
  96. return RT_EOK;
  97. }
  98. static void lpccan_init_alut_ram(void)
  99. {
  100. //Reset CANAF value
  101. LPC_CANAF->AFMR = 0x01;
  102. //clear ALUT RAM
  103. rt_memset((void *)LPC_CANAF_RAM->mask, 0, 2048);
  104. LPC_CANAF->SFF_sa = 0;
  105. LPC_CANAF->SFF_GRP_sa = 0;
  106. LPC_CANAF->EFF_sa = 0;
  107. LPC_CANAF->EFF_GRP_sa = 0;
  108. LPC_CANAF->ENDofTable = 0;
  109. LPC_CANAF->AFMR = 0x00;
  110. // Set AF Mode
  111. CAN_SetAFMode(CAN_NORMAL);
  112. }
  113. #ifdef RT_USING_LPCCAN1
  114. static void lpccan1_turnon_clk(void)
  115. {
  116. CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE);
  117. }
  118. static void lpccan1_filter_init(struct rt_can_device *can)
  119. {
  120. }
  121. static void lpccan1_hw_init(uint32_t baud, CAN_MODE_Type mode)
  122. {
  123. if(mode != CAN_SELFTEST_MODE)
  124. {
  125. #ifndef LPCCAN1_USEING_GPIO_SECOND
  126. PINSEL_ConfigPin (0, 0, 1);
  127. PINSEL_ConfigPin (0, 1, 1);
  128. #else
  129. PINSEL_ConfigPin (0, 21, 4);
  130. PINSEL_ConfigPin (0, 22, 4);
  131. #endif
  132. }
  133. lpccan1_turnon_clk();
  134. lpccan_irqstate_init(CAN_1);
  135. lpccan_init_alut_ram();
  136. lpccan1_turnon_clk();
  137. lpccan_baud_set(CAN_1, baud);
  138. CAN_ModeConfig(CAN_1, mode, ENABLE);
  139. if(mode == CAN_SELFTEST_MODE)
  140. {
  141. //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE);
  142. CAN_SetAFMode(CAN_ACC_BP);
  143. }
  144. }
  145. #endif /*RT_USING_LPCCAN1*/
  146. #ifdef RT_USING_LPCCAN2
  147. static void lpccan2_turnon_clk(void)
  148. {
  149. CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE);
  150. }
  151. static void lpccan2_filter_init(struct rt_can_device *can)
  152. {
  153. }
  154. static void lpccan2_hw_init(uint32_t baud, CAN_MODE_Type mode)
  155. {
  156. if(mode != CAN_SELFTEST_MODE)
  157. {
  158. #ifndef LPCCAN2_USEING_GPIO_SECOND
  159. PINSEL_ConfigPin (0, 4, 2);
  160. PINSEL_ConfigPin (0, 5, 2);
  161. #else
  162. PINSEL_ConfigPin (2, 7, 1);
  163. PINSEL_ConfigPin (2, 8, 1);
  164. #endif
  165. }
  166. lpccan2_turnon_clk();
  167. lpccan_irqstate_init(CAN_2);
  168. #ifndef RT_USING_LPCCAN1
  169. lpccan_init_alut_ram();
  170. #endif /*RT_USING_LPCCAN1*/
  171. lpccan_baud_set(CAN_2, baud);
  172. CAN_ModeConfig(CAN_2, mode, ENABLE);
  173. if(mode == CAN_SELFTEST_MODE)
  174. {
  175. CAN_SetAFMode(CAN_ACC_BP);
  176. }
  177. }
  178. #endif /*RT_USING_LPCCAN2*/
  179. static rt_err_t configure(struct rt_can_device *can, struct can_configure *cfg)
  180. {
  181. CAN_MODE_Type mode;
  182. rt_uint32_t canid;
  183. switch(cfg->mode)
  184. {
  185. case RT_CAN_MODE_NORMAL:
  186. mode = CAN_OPERATING_MODE;
  187. break;
  188. case RT_CAN_MODE_LISEN:
  189. mode = CAN_LISTENONLY_MODE;
  190. break;
  191. case RT_CAN_MODE_LOOPBACKANLISEN:
  192. mode = CAN_SELFTEST_MODE;
  193. break;
  194. default:
  195. return RT_EIO;
  196. }
  197. canid = ((struct lpccandata *) can->parent.user_data)->id;
  198. #ifdef RT_USING_LPCCAN1
  199. if(canid == CAN_1)
  200. {
  201. lpccan1_hw_init(cfg->baud_rate, mode);
  202. lpccan1_filter_init(can);
  203. }
  204. #endif /*RT_USING_LPCCAN1*/
  205. #ifdef RT_USING_LPCCAN2
  206. #ifdef RT_USING_LPCCAN1
  207. else
  208. #endif /*RT_USING_LPCCAN1*/
  209. {
  210. lpccan2_hw_init(cfg->baud_rate, mode);
  211. lpccan2_filter_init(can);
  212. }
  213. #endif /*RT_USING_LPCCAN2*/
  214. return RT_EOK;
  215. }
  216. static CAN_ERROR findfilter(struct lpccandata* plpccan, struct rt_can_filter_item* pitem, rt_int32_t* pos)
  217. {
  218. extern uint16_t CANAF_FullCAN_cnt;
  219. extern uint16_t CANAF_std_cnt;
  220. extern uint16_t CANAF_gstd_cnt;
  221. extern uint16_t CANAF_ext_cnt;
  222. extern uint16_t CANAF_gext_cnt;
  223. rt_uint32_t buf0 = 0, buf1 = 0;
  224. rt_int16_t cnt1 = 0, cnt2 = 0, bound1 = 0;
  225. CAN_ID_FORMAT_Type format;
  226. *pos = -1;
  227. if(pitem->ide)
  228. {
  229. format = EXT_ID_FORMAT;
  230. }
  231. else
  232. {
  233. format = STD_ID_FORMAT;
  234. }
  235. if(pitem->mode)
  236. {
  237. rt_uint32_t id = pitem->id;
  238. if(format == STD_ID_FORMAT)
  239. {
  240. id &= 0x07FF;
  241. id |= plpccan->id << 13;/* Add controller number */
  242. if (CANAF_std_cnt == 0)
  243. {
  244. return CAN_ENTRY_NOT_EXIT_ERROR;
  245. }
  246. else if (CANAF_std_cnt == 1)
  247. {
  248. cnt2 = (CANAF_FullCAN_cnt + 1) >> 1;
  249. if(id != LPC_CANAF_RAM->mask[cnt2] >> 16)
  250. {
  251. return CAN_ENTRY_NOT_EXIT_ERROR;
  252. }
  253. }
  254. else
  255. {
  256. cnt1 = (CANAF_FullCAN_cnt+1)>>1;
  257. bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
  258. while (cnt1 < bound1)
  259. {
  260. /* Loop through standard existing IDs */
  261. if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) == id)
  262. {
  263. *pos = cnt1 * 2;
  264. return CAN_OK;
  265. }
  266. if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) == id)
  267. {
  268. *pos = cnt1 * 2 + 1;
  269. return CAN_OK;
  270. }
  271. if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id)
  272. {
  273. return CAN_ENTRY_NOT_EXIT_ERROR;
  274. }
  275. if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id)
  276. {
  277. return CAN_ENTRY_NOT_EXIT_ERROR;
  278. }
  279. cnt1++;
  280. }
  281. return CAN_ENTRY_NOT_EXIT_ERROR;
  282. }
  283. }
  284. /*********** Add Explicit Extended Identifier Frame Format entry *********/
  285. else
  286. {
  287. /* Add controller number */
  288. id |= plpccan->id << 29;
  289. cnt1 = ((CANAF_FullCAN_cnt+1) >> 1) + (((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
  290. cnt2 = 0;
  291. while (cnt2 < CANAF_ext_cnt)
  292. {
  293. /* Loop through extended existing masks*/
  294. if (LPC_CANAF_RAM->mask[cnt1] == id)
  295. {
  296. *pos = cnt2;
  297. return CAN_OK;
  298. }
  299. if (LPC_CANAF_RAM->mask[cnt1] > id)
  300. {
  301. return CAN_ENTRY_NOT_EXIT_ERROR;
  302. }
  303. cnt1++;
  304. cnt2++;
  305. }
  306. }
  307. }
  308. else
  309. {
  310. rt_uint32_t lowerID = pitem->id;
  311. rt_uint32_t upperID = pitem->mask;
  312. rt_uint32_t LID,UID;
  313. if(lowerID > upperID)
  314. return CAN_CONFLICT_ID_ERROR;
  315. if(format == STD_ID_FORMAT)
  316. {
  317. lowerID &=0x7FF; //mask ID
  318. upperID &=0x7FF;
  319. cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
  320. if(CANAF_gstd_cnt == 0)
  321. {
  322. return CAN_ENTRY_NOT_EXIT_ERROR;
  323. }
  324. else
  325. {
  326. bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
  327. while(cnt1 < bound1)
  328. {
  329. //compare controller first
  330. while((LPC_CANAF_RAM->mask[cnt1] >> 29) < (plpccan->id))//increase until meet greater or equal controller
  331. cnt1++;
  332. buf0 = LPC_CANAF_RAM->mask[cnt1];
  333. if((LPC_CANAF_RAM->mask[cnt1] >> 29) > (plpccan->id)) //meet greater controller
  334. {
  335. return CAN_ENTRY_NOT_EXIT_ERROR;
  336. }
  337. else //meet equal controller
  338. {
  339. LID = (buf0 >> 16)&0x7FF;
  340. UID = buf0 & 0x7FF;
  341. if (upperID == LID && lowerID == UID)
  342. {
  343. *pos = cnt1;
  344. return CAN_OK;
  345. }
  346. if (upperID < LID)
  347. {
  348. return CAN_ENTRY_NOT_EXIT_ERROR;
  349. }
  350. else if (lowerID >= UID)
  351. {
  352. cnt1 ++;
  353. }
  354. else
  355. return CAN_CONFLICT_ID_ERROR;
  356. }
  357. }
  358. if(cnt1 >= bound1)
  359. {
  360. return CAN_ENTRY_NOT_EXIT_ERROR;
  361. }
  362. }
  363. }
  364. /*********Add Group of Extended Identifier Frame Format************/
  365. else
  366. {
  367. lowerID &= 0x1FFFFFFF; //mask ID
  368. upperID &= 0x1FFFFFFF;
  369. cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
  370. //if this is the first Group standard ID entry
  371. if(CANAF_gext_cnt == 0)
  372. {
  373. return CAN_ENTRY_NOT_EXIT_ERROR;
  374. }
  375. else
  376. {
  377. bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
  378. + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
  379. while(cnt1 < bound1)
  380. {
  381. while((LPC_CANAF_RAM->mask[cnt1] >>29)< plpccan->id ) //increase until meet greater or equal controller
  382. cnt1++;
  383. buf0 = LPC_CANAF_RAM->mask[cnt1];
  384. buf1 = LPC_CANAF_RAM->mask[cnt1+1];
  385. if((LPC_CANAF_RAM->mask[cnt1] >> 29) > plpccan->id ) //meet greater controller
  386. {
  387. return CAN_ENTRY_NOT_EXIT_ERROR;
  388. }
  389. else //meet equal controller
  390. {
  391. LID = buf0 & 0x1FFFFFFF; //mask ID
  392. UID = buf1 & 0x1FFFFFFF;
  393. if (upperID == LID && lowerID == UID)
  394. {
  395. *pos = cnt1;
  396. return CAN_OK;
  397. }
  398. if (upperID < LID)
  399. {
  400. return CAN_ENTRY_NOT_EXIT_ERROR;
  401. }
  402. else if (lowerID >= UID)
  403. {
  404. //load next entry to compare
  405. cnt1 +=2;
  406. }
  407. else
  408. return CAN_CONFLICT_ID_ERROR;
  409. }
  410. }
  411. if(cnt1 >= bound1)
  412. {
  413. return CAN_ENTRY_NOT_EXIT_ERROR;
  414. }
  415. }
  416. }
  417. }
  418. return CAN_ENTRY_NOT_EXIT_ERROR;
  419. }
  420. static rt_err_t setfilter(struct lpccandata* plpccan,struct rt_can_filter_config *pconfig)
  421. {
  422. struct rt_can_filter_item* pitem = pconfig->items;
  423. rt_uint32_t count = pconfig->count;
  424. rt_int32_t pos;
  425. CAN_ID_FORMAT_Type format;
  426. CAN_ERROR lpccanres;
  427. while(count)
  428. {
  429. if(pitem->ide)
  430. {
  431. format = EXT_ID_FORMAT;
  432. }
  433. else
  434. {
  435. format = STD_ID_FORMAT;
  436. }
  437. lpccanres = findfilter(plpccan, pitem, &pos);
  438. if(pconfig->actived && lpccanres != CAN_OK)
  439. {
  440. if(pitem->mode)
  441. {
  442. lpccanres = CAN_LoadGroupEntry(plpccan->id, pitem->id, pitem->mask, format);
  443. }
  444. else
  445. {
  446. lpccanres = CAN_LoadExplicitEntry(plpccan->id, pitem->id, format);
  447. }
  448. }
  449. else if(!pconfig->actived && lpccanres == CAN_OK)
  450. {
  451. AFLUT_ENTRY_Type type;
  452. if(pitem->mode)
  453. {
  454. if(format == EXT_ID_FORMAT)
  455. {
  456. type = GROUP_EXTEND_ENTRY;
  457. }
  458. else
  459. {
  460. type = GROUP_STANDARD_ENTRY;
  461. }
  462. }
  463. else
  464. {
  465. if(format == EXT_ID_FORMAT)
  466. {
  467. type = EXPLICIT_EXTEND_ENTRY;
  468. }
  469. else
  470. {
  471. type = EXPLICIT_STANDARD_ENTRY;
  472. }
  473. }
  474. lpccanres = CAN_RemoveEntry(type, (rt_uint16_t)(pos));
  475. }
  476. else if(!pconfig->actived && lpccanres != CAN_OK)
  477. {
  478. lpccanres = CAN_OK;
  479. }
  480. if(lpccanres != CAN_OK)
  481. {
  482. return RT_EIO;
  483. }
  484. pitem++;
  485. count--;
  486. }
  487. return RT_EOK;
  488. }
  489. static rt_err_t control(struct rt_can_device *can, int cmd, void *arg)
  490. {
  491. struct lpccandata* plpccan;
  492. rt_uint32_t argval;
  493. CAN_MODE_Type mode;
  494. plpccan = (struct lpccandata* ) can->parent.user_data;
  495. RT_ASSERT(plpccan != RT_NULL);
  496. switch (cmd)
  497. {
  498. case RT_DEVICE_CTRL_CLR_INT:
  499. argval = (rt_uint32_t) arg;
  500. if(argval == RT_DEVICE_FLAG_INT_RX)
  501. {
  502. CAN_IRQCmd(plpccan->id, CANINT_RIE, DISABLE);
  503. CAN_IRQCmd(plpccan->id, CANINT_DOIE, DISABLE);
  504. }
  505. else if(argval == RT_DEVICE_FLAG_INT_TX)
  506. {
  507. CAN_IRQCmd(plpccan->id, CANINT_TIE1, DISABLE);
  508. CAN_IRQCmd(plpccan->id, CANINT_TIE2, DISABLE);
  509. CAN_IRQCmd(plpccan->id, CANINT_TIE3, DISABLE);
  510. }
  511. else if(argval == RT_DEVICE_CAN_INT_ERR)
  512. {
  513. CAN_IRQCmd(plpccan->id, CANINT_EIE, DISABLE);
  514. }
  515. break;
  516. case RT_DEVICE_CTRL_SET_INT:
  517. argval = (rt_uint32_t) arg;
  518. if(argval == RT_DEVICE_FLAG_INT_RX)
  519. {
  520. CAN_IRQCmd(plpccan->id, CANINT_RIE, ENABLE);
  521. CAN_IRQCmd(plpccan->id, CANINT_DOIE, ENABLE);
  522. }
  523. else if(argval == RT_DEVICE_FLAG_INT_TX)
  524. {
  525. CAN_IRQCmd(plpccan->id, CANINT_TIE1, ENABLE);
  526. CAN_IRQCmd(plpccan->id, CANINT_TIE2, ENABLE);
  527. CAN_IRQCmd(plpccan->id, CANINT_TIE3, ENABLE);
  528. }
  529. else if(argval == RT_DEVICE_CAN_INT_ERR)
  530. {
  531. CAN_IRQCmd(plpccan->id, CANINT_EIE, ENABLE);
  532. }
  533. break;
  534. case RT_CAN_CMD_SET_FILTER:
  535. return setfilter(plpccan, (struct rt_can_filter_config*) arg);
  536. case RT_CAN_CMD_SET_MODE:
  537. argval = (rt_uint32_t) arg;
  538. if(argval != RT_CAN_MODE_NORMAL ||
  539. argval != RT_CAN_MODE_LISEN)
  540. {
  541. return RT_ERROR;
  542. }
  543. if(argval != can->config.mode)
  544. {
  545. can->config.mode = argval;
  546. switch(argval)
  547. {
  548. case RT_CAN_MODE_NORMAL:
  549. mode = CAN_OPERATING_MODE;
  550. break;
  551. case RT_CAN_MODE_LISEN:
  552. mode = CAN_LISTENONLY_MODE;
  553. break;
  554. case RT_CAN_MODE_LOOPBACKANLISEN:
  555. mode = CAN_SELFTEST_MODE;
  556. break;
  557. default:
  558. return RT_EIO;
  559. }
  560. CAN_ModeConfig(plpccan->id, mode, ENABLE);
  561. if(mode == CAN_SELFTEST_MODE)
  562. {
  563. //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE);
  564. CAN_SetAFMode(CAN_ACC_BP);
  565. }
  566. }
  567. break;
  568. case RT_CAN_CMD_SET_BAUD:
  569. argval = (rt_uint32_t) arg;
  570. if(argval != can->config.baud_rate)
  571. {
  572. can->config.baud_rate = argval;
  573. return lpccan_baud_set(plpccan->id, (rt_uint32_t) arg);
  574. }
  575. break;
  576. case RT_CAN_CMD_SET_PRIV:
  577. argval = (rt_uint32_t) arg;
  578. if(argval != RT_CAN_MODE_PRIV ||
  579. argval != RT_CAN_MODE_NOPRIV)
  580. {
  581. return RT_ERROR;
  582. }
  583. if(argval != can->config.privmode)
  584. {
  585. can->config.privmode = argval;
  586. CAN_ModeConfig(plpccan->id, CAN_TXPRIORITY_MODE, ENABLE);
  587. }
  588. break;
  589. case RT_CAN_CMD_GET_STATUS:
  590. {
  591. can->status.rcverrcnt = 0;
  592. can->status.snderrcnt = 0;
  593. can->status.errcode = 0;
  594. if(arg != &can->status)
  595. {
  596. rt_memcpy(arg,&can->status,sizeof(can->status));
  597. }
  598. }
  599. break;
  600. }
  601. return RT_EOK;
  602. }
  603. static int sendmsg(struct rt_can_device *can, const void* buf, rt_uint32_t boxno)
  604. {
  605. struct lpccandata* plpccan;
  606. LPC_CAN_TypeDef* pCan;
  607. struct rt_can_msg* pmsg;
  608. rt_uint32_t SR_Mask;
  609. rt_uint32_t CMRMsk;
  610. plpccan = (struct lpccandata* ) can->parent.user_data;
  611. RT_ASSERT(plpccan != RT_NULL);
  612. pCan = lcpcan_get_reg_base(plpccan->id);
  613. RT_ASSERT(pCan != RT_NULL);
  614. pmsg = (struct rt_can_msg*) buf;
  615. if(boxno > 2)
  616. {
  617. return RT_ERROR;
  618. }
  619. CMRMsk = 0x01 | (0x01 << (boxno + 5));
  620. SR_Mask = 0x01 <<(boxno * 8 + 2);
  621. if(pCan->SR & SR_Mask)
  622. {
  623. volatile unsigned int *pTFI = (&pCan->TFI1 + 0 + 4 * boxno);
  624. volatile unsigned int *pTID = (&pCan->TFI1 + 1 + 4 * boxno);
  625. volatile unsigned int *pTDA = (&pCan->TFI1 + 2 + 4 * boxno);
  626. volatile unsigned int *pTDB = (&pCan->TFI1 + 3 + 4 * boxno);
  627. rt_uint32_t data;
  628. /* Transmit Channel 1 is available */
  629. /* Write frame informations and frame data into its CANxTFI1,
  630. * CANxTID1, CANxTDA1, CANxTDB1 register */
  631. *pTFI &= ~ 0x000F0000;
  632. *pTFI |= (pmsg->len) << 16;
  633. if(pmsg->rtr == REMOTE_FRAME)
  634. {
  635. *pTFI |= (1 << 30); //set bit RTR
  636. }
  637. else
  638. {
  639. *pTFI &= ~(1 << 30);
  640. }
  641. if(pmsg->ide == EXT_ID_FORMAT)
  642. {
  643. *pTFI |= (((uint32_t)1) << 31); //set bit FF
  644. }
  645. else
  646. {
  647. *pTFI &= ~(((uint32_t)1) << 31);
  648. }
  649. if(can->config.privmode)
  650. {
  651. *pTFI &= ~0x000000FF;
  652. *pTFI |= pmsg->priv;
  653. }
  654. /* Write CAN ID*/
  655. *pTID = pmsg->id;
  656. /*Write first 4 data bytes*/
  657. data = (pmsg->data[0]) | (((pmsg->data[1]))<< 8) | ((pmsg->data[2]) << 16) | ((pmsg->data[3]) << 24);
  658. *pTDA = data;
  659. /*Write second 4 data bytes*/
  660. data = (pmsg->data[4]) | (((pmsg->data[5])) << 8) | ((pmsg->data[6]) << 16) | ((pmsg->data[7]) << 24);
  661. *pTDB = data;
  662. /*Write transmission request*/
  663. pCan->CMR = CMRMsk;
  664. return RT_EOK;
  665. }
  666. else
  667. {
  668. return RT_ERROR;
  669. }
  670. }
  671. static int recvmsg(struct rt_can_device *can, void* buf, rt_uint32_t boxno)
  672. {
  673. struct lpccandata* plpccan;
  674. LPC_CAN_TypeDef* pCan;
  675. plpccan = (struct lpccandata* ) can->parent.user_data;
  676. RT_ASSERT(plpccan != RT_NULL);
  677. pCan = lcpcan_get_reg_base(plpccan->id);
  678. RT_ASSERT(pCan != RT_NULL);
  679. //CAN_ReceiveMsg
  680. //check status of Receive Buffer
  681. if((pCan->SR &0x00000001))
  682. {
  683. uint32_t data;
  684. struct rt_can_msg* pmsg = (struct rt_can_msg*) buf;
  685. /* Receive message is available */
  686. /* Read frame informations */
  687. pmsg->ide = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31);
  688. pmsg->rtr = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30);
  689. pmsg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16);
  690. /* Read CAN message identifier */
  691. pmsg->id = pCan->RID;
  692. /* Read the data if received message was DATA FRAME */
  693. if (!pmsg->rtr)
  694. {
  695. /* Read first 4 data bytes */
  696. data = pCan->RDA;
  697. pmsg->data[0] = data & 0x000000FF;
  698. pmsg->data[1] = (data & 0x0000FF00) >> 8;
  699. pmsg->data[2] = (data & 0x00FF0000) >> 16;
  700. pmsg->data[3] = (data & 0xFF000000) >> 24;
  701. /* Read second 4 data bytes */
  702. if(pmsg->len > 4)
  703. {
  704. data = pCan->RDB;
  705. pmsg->data[4] = data & 0x000000FF;
  706. pmsg->data[5] = (data & 0x0000FF00) >> 8;
  707. pmsg->data[6] = (data & 0x00FF0000) >> 16;
  708. pmsg->data[7] = (data & 0xFF000000) >> 24;
  709. }
  710. pmsg->hdr = 0;
  711. /*release receive buffer*/
  712. pCan->CMR = 0x04;
  713. }
  714. else
  715. {
  716. /* Received Frame is a Remote Frame, not have data, we just receive
  717. * message information only */
  718. pCan->CMR = 0x04; /*release receive buffer*/
  719. return SUCCESS;
  720. }
  721. }
  722. else
  723. {
  724. // no receive message available
  725. return ERROR;
  726. }
  727. return RT_EOK;
  728. }
  729. static const struct rt_can_ops canops =
  730. {
  731. configure,
  732. control,
  733. sendmsg,
  734. recvmsg,
  735. };
  736. #ifdef RT_USING_LPCCAN1
  737. #ifdef RT_CAN_USING_LED
  738. #endif
  739. static struct lpccandata lpccandata1 =
  740. {
  741. CAN_ID_1,
  742. };
  743. static struct rt_can_device lpccan1;
  744. #endif /*RT_USINGLPCCAN1*/
  745. #ifdef RT_USING_LPCCAN2
  746. #ifdef RT_CAN_USING_LED
  747. #endif
  748. static struct lpccandata lpccandata2 =
  749. {
  750. CAN_ID_2,
  751. };
  752. static struct rt_can_device lpccan2;
  753. #endif /*RT_USINGLPCCAN2*/
  754. /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
  755. /*********************************************************************//**
  756. * @brief Event Router IRQ Handler
  757. * @param[in] None
  758. * @return None
  759. **********************************************************************/
  760. void CAN_IRQHandler(void)
  761. {
  762. rt_uint32_t IntStatus;
  763. rt_interrupt_enter();
  764. #ifdef RT_USING_LPCCAN1
  765. IntStatus = CAN_IntGetStatus(CAN_1);
  766. //check receive interrupt
  767. if((IntStatus >> 0) & 0x01)
  768. {
  769. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RX_IND | 0<<8);
  770. }
  771. //check Transmit Interrupt interrupt1
  772. if((IntStatus >> 1) & 0x01)
  773. {
  774. rt_uint32_t state = 0;
  775. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  776. if(state & (0x01 << 3))
  777. {
  778. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
  779. }
  780. else
  781. {
  782. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
  783. }
  784. }
  785. //check Error Warning Interrupt
  786. if((IntStatus >> 2) & 0x01)
  787. {
  788. rt_uint32_t errtype;
  789. rt_uint32_t state;
  790. errtype = (IntStatus >> 16);
  791. if(errtype & 0x1F && lpccan1.status.lasterrtype == (errtype & 0x1F))
  792. {
  793. switch((errtype & 0x1F))
  794. {
  795. case 00011: // Start of Frame
  796. case 00010: // ID28 ... ID21
  797. case 00110: //ID20 ... ID18
  798. case 00100: // SRTR Bit
  799. case 00101: // IDE bit
  800. case 00111: // ID17 ... 13
  801. case 01111: // ID12 ... ID5
  802. case 01110: // ID4 ... ID0
  803. case 01100: // RTR Bit
  804. case 01011: // Data Length Code
  805. case 01010: // Data Field
  806. lpccan1.status.formaterrcnt++;
  807. break;
  808. case 01101: // Reserved Bit 1
  809. case 01001: // Reserved Bit 0
  810. lpccan1.status.bitpaderrcnt++;
  811. break;
  812. case 01000: // CRC Sequence
  813. case 11000: // CRC Delimiter
  814. lpccan1.status.crcerrcnt++;
  815. break;
  816. case 11001: // Acknowledge Slot
  817. case 11011: // Acknowledge Delimiter
  818. lpccan1.status.ackerrcnt++;
  819. break;
  820. case 11010: // End of Frame
  821. case 10010: // Intermission
  822. lpccan1.status.formaterrcnt++;
  823. break;
  824. }
  825. lpccan1.status.lasterrtype = errtype & 0x1F;
  826. }
  827. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_GLOBAL_STS);
  828. lpccan1.status.rcverrcnt = (state >> 16) & 0xFF;
  829. lpccan1.status.snderrcnt = (state >> 24) & 0xFF;
  830. lpccan1.status.errcode = (state >> 5) & 0x06;
  831. }
  832. //check Data Overrun Interrupt Interrupt
  833. if((IntStatus >> 3) & 0x01)
  834. {
  835. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
  836. }
  837. //check Transmit Interrupt interrupt2
  838. if((IntStatus >> 9) & 0x01)
  839. {
  840. rt_uint32_t state = 0;
  841. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  842. if(state & (0x01 << 11))
  843. {
  844. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
  845. }
  846. else
  847. {
  848. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
  849. }
  850. }
  851. //check Transmit Interrupt interrupt3
  852. if((IntStatus >> 10) & 0x01)
  853. {
  854. rt_uint32_t state = 0;
  855. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  856. if(state & (0x01 << 19))
  857. {
  858. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
  859. }
  860. else
  861. {
  862. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
  863. }
  864. }
  865. #endif /*RT_USING_LPCCAN1*/
  866. #ifdef RT_USING_LPCCAN2
  867. IntStatus = CAN_IntGetStatus(CAN_2);
  868. //check receive interrupt
  869. if((IntStatus >> 0) & 0x01)
  870. {
  871. rt_hw_can_isr(&lpccan2,RT_CAN_EVENT_RX_IND | 0<<8);
  872. }
  873. //check Transmit Interrupt interrupt1
  874. if((IntStatus >> 1) & 0x01)
  875. {
  876. rt_uint32_t state = 0;
  877. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  878. if(state & (0x01 << 3))
  879. {
  880. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
  881. }
  882. else
  883. {
  884. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
  885. }
  886. }
  887. //check Error Warning Interrupt
  888. if((IntStatus >> 2) & 0x01)
  889. {
  890. rt_uint32_t errtype;
  891. errtype = (IntStatus >> 16);
  892. if(errtype & 0x1F && lpccan2.status.lasterrtype == (errtype & 0x1F))
  893. {
  894. switch((errtype & 0x1F))
  895. {
  896. case 00011: // Start of Frame
  897. case 00010: // ID28 ... ID21
  898. case 00110: //ID20 ... ID18
  899. case 00100: // SRTR Bit
  900. case 00101: // IDE bit
  901. case 00111: // ID17 ... 13
  902. case 01111: // ID12 ... ID5
  903. case 01110: // ID4 ... ID0
  904. case 01100: // RTR Bit
  905. case 01011: // Data Length Code
  906. case 01010: // Data Field
  907. lpccan2.status.formaterrcnt++;
  908. break;
  909. case 01101: // Reserved Bit 1
  910. case 01001: // Reserved Bit 0
  911. lpccan2.status.bitpaderrcnt++;
  912. break;
  913. case 01000: // CRC Sequence
  914. case 11000: // CRC Delimiter
  915. lpccan2.status.crcerrcnt++;
  916. break;
  917. case 11001: // Acknowledge Slot
  918. case 11011: // Acknowledge Delimiter
  919. lpccan2.status.ackerrcnt++;
  920. break;
  921. case 11010: // End of Frame
  922. case 10010: // Intermission
  923. lpccan2.status.formaterrcnt++;
  924. break;
  925. }
  926. lpccan2.status.lasterrtype = errtype & 0x1F;
  927. }
  928. rt_uint32_t state = 0;
  929. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_GLOBAL_STS);
  930. lpccan2.status.rcverrcnt = (state >> 16) & 0xFF;
  931. lpccan2.status.snderrcnt = (state >> 24) & 0xFF;
  932. lpccan2.status.errcode = (state >> 5) & 0x06;
  933. }
  934. //check Data Overrun Interrupt Interrupt
  935. if((IntStatus >> 3) & 0x01)
  936. {
  937. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
  938. }
  939. //check Transmit Interrupt interrupt2
  940. if((IntStatus >> 9) & 0x01)
  941. {
  942. rt_uint32_t state = 0;
  943. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  944. if(state & (0x01 << 11))
  945. {
  946. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
  947. }
  948. else
  949. {
  950. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
  951. }
  952. }
  953. //check Transmit Interrupt interrupt3
  954. if((IntStatus >> 10) & 0x01)
  955. {
  956. rt_uint32_t state = 0;
  957. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  958. if(state & (0x01 << 19))
  959. {
  960. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
  961. }
  962. else
  963. {
  964. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
  965. }
  966. }
  967. #endif /*RT_USING_LPCCAN2*/
  968. rt_interrupt_leave();
  969. }
  970. int lpc_can_init(void)
  971. {
  972. #ifdef RT_USING_LPCCAN1
  973. lpccan1.config.baud_rate=CAN1MBaud;
  974. lpccan1.config.msgboxsz=16;
  975. lpccan1.config.sndboxnumber=3;
  976. lpccan1.config.mode=RT_CAN_MODE_NORMAL;
  977. lpccan1.config.privmode=0;
  978. #ifdef RT_CAN_USING_LED
  979. #endif
  980. lpccan1.config.ticks = 50;
  981. #ifdef RT_CAN_USING_HDR
  982. #endif
  983. //Enable CAN Interrupt
  984. NVIC_EnableIRQ(CAN_IRQn);
  985. rt_hw_can_register(&lpccan1, "lpccan1", &canops, &lpccandata1);
  986. #endif /*RT_USING_LPCCAN1*/
  987. #ifdef RT_USING_LPCCAN2
  988. lpccan2.config.baud_rate=CAN1MBaud;
  989. lpccan2.config.msgboxsz=16;
  990. lpccan2.config.sndboxnumber=3;
  991. lpccan2.config.mode=RT_CAN_MODE_NORMAL;
  992. lpccan2.config.privmode=0;
  993. #ifdef RT_CAN_USING_LED
  994. #endif
  995. lpccan2.config.ticks = 50;
  996. #ifdef RT_CAN_USING_HDR
  997. #endif
  998. //Enable CAN Interrupt
  999. NVIC_EnableIRQ(CAN_IRQn);
  1000. #ifdef RT_CAN_USING_HDR
  1001. #endif
  1002. rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2);
  1003. #endif /*RT_USING_LPCCAN2*/
  1004. return RT_EOK;
  1005. }
  1006. INIT_BOARD_EXPORT(lpc_can_init);
  1007. #endif /*RT_USING_CAN*/