drv_lpccan.c 30 KB

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