drv_lpccan.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  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. #ifdef RT_USING_LPCCAN1
  764. IntStatus = CAN_IntGetStatus(CAN_1);
  765. //check receive interrupt
  766. if((IntStatus >> 0) & 0x01)
  767. {
  768. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RX_IND | 0<<8);
  769. }
  770. //check Transmit Interrupt interrupt1
  771. if((IntStatus >> 1) & 0x01)
  772. {
  773. rt_uint32_t state = 0;
  774. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  775. if(state & (0x01 << 3))
  776. {
  777. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
  778. }
  779. else
  780. {
  781. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
  782. }
  783. }
  784. //check Error Warning Interrupt
  785. if((IntStatus >> 2) & 0x01)
  786. {
  787. rt_uint32_t errtype;
  788. rt_uint32_t state;
  789. errtype = (IntStatus >> 16);
  790. if(errtype & 0x1F && lpccan1.status.lasterrtype == (errtype & 0x1F))
  791. {
  792. switch((errtype & 0x1F))
  793. {
  794. case 00011: // Start of Frame
  795. case 00010: // ID28 ... ID21
  796. case 00110: //ID20 ... ID18
  797. case 00100: // SRTR Bit
  798. case 00101: // IDE bit
  799. case 00111: // ID17 ... 13
  800. case 01111: // ID12 ... ID5
  801. case 01110: // ID4 ... ID0
  802. case 01100: // RTR Bit
  803. case 01011: // Data Length Code
  804. case 01010: // Data Field
  805. lpccan1.status.formaterrcnt++;
  806. break;
  807. case 01101: // Reserved Bit 1
  808. case 01001: // Reserved Bit 0
  809. lpccan1.status.bitpaderrcnt++;
  810. break;
  811. case 01000: // CRC Sequence
  812. case 11000: // CRC Delimiter
  813. lpccan1.status.crcerrcnt++;
  814. break;
  815. case 11001: // Acknowledge Slot
  816. case 11011: // Acknowledge Delimiter
  817. lpccan1.status.ackerrcnt++;
  818. break;
  819. case 11010: // End of Frame
  820. case 10010: // Intermission
  821. lpccan1.status.formaterrcnt++;
  822. break;
  823. }
  824. lpccan1.status.lasterrtype = errtype & 0x1F;
  825. }
  826. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_GLOBAL_STS);
  827. lpccan1.status.rcverrcnt = (state >> 16) & 0xFF;
  828. lpccan1.status.snderrcnt = (state >> 24) & 0xFF;
  829. lpccan1.status.errcode = (state >> 5) & 0x06;
  830. }
  831. //check Data Overrun Interrupt Interrupt
  832. if((IntStatus >> 3) & 0x01)
  833. {
  834. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
  835. }
  836. //check Transmit Interrupt interrupt2
  837. if((IntStatus >> 9) & 0x01)
  838. {
  839. rt_uint32_t state = 0;
  840. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  841. if(state & (0x01 << 11))
  842. {
  843. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
  844. }
  845. else
  846. {
  847. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
  848. }
  849. }
  850. //check Transmit Interrupt interrupt3
  851. if((IntStatus >> 10) & 0x01)
  852. {
  853. rt_uint32_t state = 0;
  854. state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS);
  855. if(state & (0x01 << 19))
  856. {
  857. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
  858. }
  859. else
  860. {
  861. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
  862. }
  863. }
  864. #endif /*RT_USING_LPCCAN1*/
  865. #ifdef RT_USING_LPCCAN2
  866. IntStatus = CAN_IntGetStatus(CAN_2);
  867. //check receive interrupt
  868. if((IntStatus >> 0) & 0x01)
  869. {
  870. rt_hw_can_isr(&lpccan2,RT_CAN_EVENT_RX_IND | 0<<8);
  871. }
  872. //check Transmit Interrupt interrupt1
  873. if((IntStatus >> 1) & 0x01)
  874. {
  875. rt_uint32_t state = 0;
  876. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  877. if(state & (0x01 << 3))
  878. {
  879. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8);
  880. }
  881. else
  882. {
  883. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8);
  884. }
  885. }
  886. //check Error Warning Interrupt
  887. if((IntStatus >> 2) & 0x01)
  888. {
  889. rt_uint32_t errtype;
  890. errtype = (IntStatus >> 16);
  891. if(errtype & 0x1F && lpccan2.status.lasterrtype == (errtype & 0x1F))
  892. {
  893. switch((errtype & 0x1F))
  894. {
  895. case 00011: // Start of Frame
  896. case 00010: // ID28 ... ID21
  897. case 00110: //ID20 ... ID18
  898. case 00100: // SRTR Bit
  899. case 00101: // IDE bit
  900. case 00111: // ID17 ... 13
  901. case 01111: // ID12 ... ID5
  902. case 01110: // ID4 ... ID0
  903. case 01100: // RTR Bit
  904. case 01011: // Data Length Code
  905. case 01010: // Data Field
  906. lpccan2.status.formaterrcnt++;
  907. break;
  908. case 01101: // Reserved Bit 1
  909. case 01001: // Reserved Bit 0
  910. lpccan2.status.bitpaderrcnt++;
  911. break;
  912. case 01000: // CRC Sequence
  913. case 11000: // CRC Delimiter
  914. lpccan2.status.crcerrcnt++;
  915. break;
  916. case 11001: // Acknowledge Slot
  917. case 11011: // Acknowledge Delimiter
  918. lpccan2.status.ackerrcnt++;
  919. break;
  920. case 11010: // End of Frame
  921. case 10010: // Intermission
  922. lpccan2.status.formaterrcnt++;
  923. break;
  924. }
  925. lpccan2.status.lasterrtype = errtype & 0x1F;
  926. }
  927. rt_uint32_t state = 0;
  928. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_GLOBAL_STS);
  929. lpccan2.status.rcverrcnt = (state >> 16) & 0xFF;
  930. lpccan2.status.snderrcnt = (state >> 24) & 0xFF;
  931. lpccan2.status.errcode = (state >> 5) & 0x06;
  932. }
  933. //check Data Overrun Interrupt Interrupt
  934. if((IntStatus >> 3) & 0x01)
  935. {
  936. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8);
  937. }
  938. //check Transmit Interrupt interrupt2
  939. if((IntStatus >> 9) & 0x01)
  940. {
  941. rt_uint32_t state = 0;
  942. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  943. if(state & (0x01 << 11))
  944. {
  945. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8);
  946. }
  947. else
  948. {
  949. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8);
  950. }
  951. }
  952. //check Transmit Interrupt interrupt3
  953. if((IntStatus >> 10) & 0x01)
  954. {
  955. rt_uint32_t state = 0;
  956. state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS);
  957. if(state & (0x01 << 19))
  958. {
  959. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8);
  960. }
  961. else
  962. {
  963. rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8);
  964. }
  965. }
  966. #endif /*RT_USING_LPCCAN2*/
  967. }
  968. int lpc_can_init(void)
  969. {
  970. #ifdef RT_USING_LPCCAN1
  971. lpccan1.config.baud_rate=CAN1MBaud;
  972. lpccan1.config.msgboxsz=16;
  973. lpccan1.config.sndboxnumber=3;
  974. lpccan1.config.mode=RT_CAN_MODE_NORMAL;
  975. lpccan1.config.privmode=0;
  976. #ifdef RT_CAN_USING_LED
  977. #endif
  978. lpccan1.config.ticks = 50;
  979. #ifdef RT_CAN_USING_HDR
  980. #endif
  981. //Enable CAN Interrupt
  982. NVIC_EnableIRQ(CAN_IRQn);
  983. rt_hw_can_register(&lpccan1, "lpccan1", &canops, &lpccandata1);
  984. #endif /*RT_USING_LPCCAN1*/
  985. #ifdef RT_USING_LPCCAN2
  986. lpccan2.config.baud_rate=CAN1MBaud;
  987. lpccan2.config.msgboxsz=16;
  988. lpccan2.config.sndboxnumber=3;
  989. lpccan2.config.mode=RT_CAN_MODE_NORMAL;
  990. lpccan2.config.privmode=0;
  991. #ifdef RT_CAN_USING_LED
  992. #endif
  993. lpccan2.config.ticks = 50;
  994. #ifdef RT_CAN_USING_HDR
  995. #endif
  996. //Enable CAN Interrupt
  997. NVIC_EnableIRQ(CAN_IRQn);
  998. #ifdef RT_CAN_USING_HDR
  999. #endif
  1000. rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2);
  1001. #endif /*RT_USING_LPCCAN2*/
  1002. return RT_EOK;
  1003. }
  1004. INIT_BOARD_EXPORT(lpc_can_init);
  1005. #endif /*RT_USING_CAN*/