drv_lpccan.c 30 KB

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