flexcan.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: flexcan.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2013-02-03
  7. 功能说明: FLEXCAN驱动
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "bspconfig.h"
  14. #include "rt.h"
  15. // sunxi 20220408 #include "mcf5441x_gpio.h"
  16. // sunxi 20220408 #include "mcf5441x_flexcan.h"
  17. #include "flexcan.h"
  18. #ifdef BSP_CAN_ENABLE
  19. /*------------------------------- 宏定义 --------------------------------------
  20. */
  21. #define CAN_FIFO
  22. // 优先级
  23. #define CAN_PRIO_MAX 4
  24. // 短帧BUF
  25. #define CAN_FRAME_NUM 256 // CAN短帧BUF数量
  26. #define CAN_FRAME_LEN 16 // CAN短帧BUF长度
  27. #define CAN_FRAME_HEAD_LEN 8 // CAN短帧帧头长度
  28. #define CAN_FRAME_DATA_LEN 8 // CAN短帧数据长度
  29. // 长帧BUF
  30. #define CAN_LONGFRAME_NUM 16 // CAN长帧BUF数量
  31. #define CAN_LONGFRAME_LEN CAN_FRAME_LEN_MAX // CAN长帧BUF长度
  32. #define CAN_LONGFRAME_HEAD_LEN 4 // CAN长帧头长度
  33. #define CAN_LONGFRAME_DATA_LEN (CAN_LONGFRAME_LEN-CAN_LONGFRAME_HEAD_LEN) // CAN长帧数据长度
  34. // 帧标志,数字越小,优先级越高
  35. #define CAN_FRAME_SINGLE 0 // 单帧(既是起始帧,又是结束帧)
  36. #define CAN_FRAME_END 1 // 结束帧
  37. #define CAN_FRAME_MIDDLE 2 // 中间帧
  38. #define CAN_FRAME_BEGIN 3 // 开始帧
  39. //帧ID中各个域的位偏移
  40. #define CAN_FRAME_OFFSET_SN 0 // 帧序号偏移
  41. #define CAN_FRAME_OFFSET_MARK 6 // 帧标志偏移
  42. #define CAN_FRAME_OFFSET_SRC 8 // 帧源地址偏移
  43. #define CAN_FRAME_OFFSET_DST 12 // 帧目的地址偏移
  44. #define CAN_FRAME_OFFSET_TYPE 16 // 帧类型偏移
  45. #define CAN_FRAME_OFFSET_PRIOR 23 // 帧优先级偏移(帧优先级是帧类型的高2位)
  46. #define CAN_FRAME_OFFSET_LEN 16 // 帧长度偏移
  47. #define CAN_FRAME_MASK_SN 0X3F // 帧序号屏蔽位
  48. #define CAN_FRAME_MASK_MARK 0X03 // 帧标志屏蔽位
  49. #define CAN_FRAME_MASK_SRC 0X0F // 帧源地址屏蔽位
  50. #define CAN_FRAME_MASK_DST 0X0F // 帧目的地址屏蔽位
  51. #define CAN_FRAME_MASK_TYPE 0XFF // 帧类型屏蔽位
  52. #define CAN_FRAME_MASK_PRIOR 0X03 // 帧优先级屏蔽位(帧优先级是帧类型的高2位)
  53. #define CAN_FRAME_MASK_LEN 0X0F // 帧长度屏蔽位
  54. //缓冲区为空
  55. #define CAN_BUF_EMPTY(ring) ((ring)->head == (ring)->tail)
  56. //缓冲区满
  57. #define CAN_BUF_FULL(ring, size) (((unsigned char)((ring)->head - (ring)->tail))==((unsigned char)(size-1)))
  58. //缓冲区剩余空间
  59. #define CAN_BUF_SPACE(ring, size) (((unsigned char)((ring)->tail - (ring)->head) -1) & (unsigned char)(size-1))
  60. //强制中断寄存器
  61. #define REG_MCF_INTFRCL1 (*( volatile unsigned int*)(0xFC04C014))
  62. // 调试开关
  63. // #define CAN_DEBUG
  64. #ifdef CAN_DEBUG
  65. # define can_printf(x...) rt_printf(x)
  66. #else
  67. # define can_printf(x...)
  68. #endif
  69. // 打印报文
  70. #ifdef CAN_DEBUG
  71. # define can_print_mem(x...) print_mem_time(x)
  72. #else
  73. # define can_print_mem(x...)
  74. #endif
  75. /*------------------------------ 类型结构 -------------------------------------
  76. */
  77. // 保证所有结构的大小都是4的倍数
  78. //长帧缓冲区
  79. struct can_longframe_buf
  80. {
  81. unsigned char head;//头位置
  82. unsigned char tail;//尾位置
  83. unsigned char reserverd[2];
  84. unsigned char buf[CAN_LONGFRAME_NUM][CAN_LONGFRAME_LEN];
  85. };
  86. //缓冲区描述符
  87. struct can_buf
  88. {
  89. unsigned char head; //头位置
  90. unsigned char tail; //尾位置
  91. unsigned char frameno; //帧序号
  92. unsigned char reserverd;
  93. unsigned char buf[CAN_FRAME_NUM][CAN_FRAME_LEN];
  94. };
  95. //CAN统计信息数据结构
  96. struct can_dev_stats{
  97. uint32_t rx_shortframes; //接收短帧数
  98. uint32_t tx_shortframes; //发送短帧数
  99. uint32_t rx_longframes; //接收长帧数
  100. uint32_t tx_longframes; //发送长帧数
  101. uint32_t rx_dropped; //接收缓冲区满溢出次数
  102. uint32_t tx_dropped; //发送缓冲区满溢出次数
  103. uint32_t hw_bus_errors;
  104. uint32_t overrun;
  105. uint32_t max_mbcnt; //统计最大的未处理的MB个数
  106. uint32_t max_proctime; //处理MB的最大时间
  107. };
  108. #if 0
  109. //短帧描述符
  110. struct can_shortframe_des
  111. {
  112. unsigned char info;
  113. unsigned char flag1;
  114. unsigned char srcaddr;
  115. unsigned char dstaddr;
  116. unsigned char frameno;
  117. unsigned char data[8];
  118. unsigned char reserved[3];
  119. };
  120. #endif
  121. //时间戳差值数据结构
  122. struct can_timestamp
  123. {
  124. unsigned short timestamp; //时间戳差值,该差值是指当前时间戳与有数据的MB的时间戳差值
  125. short caniflg_bit; //MB下标即是那一个MB
  126. };
  127. //flexcan 设备数据结构
  128. struct can_dev
  129. {
  130. uint32_t no;
  131. uint32_t base_addr;
  132. struct can_dev_stats stats; //网络统计信息
  133. struct can_timestamp ts[CAN_MB]; //记录各时间戳差值
  134. struct can_buf tx_buf[CAN_PRIO_MAX]; //发送缓冲区
  135. struct can_buf rx_buf[CAN_PRIO_MAX]; //接收缓冲区
  136. struct can_longframe_buf longframe_buf_rx[CAN_PRIO_MAX]; //接收长帧缓冲区
  137. };
  138. /* Message type access macros.*/
  139. #define FLEXCAN_SET_MODE_RETRIES 255
  140. /* Message Buffer 0 configure as Tx */
  141. #define SEND_BUF 15
  142. #define SEND_BUF_BIT (1<<SEND_BUF)
  143. /* Structure of the message buffer */
  144. struct can_mb
  145. {
  146. volatile u32 can_dlc;
  147. volatile u32 can_id;
  148. u8 data[8];
  149. };
  150. struct can_regs
  151. {
  152. volatile u32 canmcr; /* FLEXCAN 0x00 */
  153. volatile u32 canctrl; /* FLEXCAN 0x04 */
  154. volatile u32 cantimer; /* FLEXCAN 0x08 */
  155. volatile u32 reserved1;
  156. volatile u32 canrxgmsk; /* FLEXCAN 0x10 */
  157. volatile u32 canrx14msk; /* FLEXCAN 0x14 */
  158. volatile u32 canrx15msk; /* FLEXCAN 0x18 */
  159. volatile u32 canerrcnt; /* FLEXCAN 0x1C */
  160. volatile u32 canerrstat; /* FLEXCAN 0x20 */
  161. volatile u32 reserved2;
  162. volatile u32 canimask; /* FLEXCAN 0x28 */
  163. volatile u32 reserved3;
  164. volatile u32 caniflg; /* FLEXCAN 0x30 */
  165. volatile u32 reserved4[19];
  166. struct can_mb cantxfg[CAN_MB];
  167. volatile u32 reserved5[448];
  168. volatile u32 rximr[CAN_MB];
  169. };
  170. /* @clock_src:
  171. 1 = The FLEXCAN clock source is the onchip Bus Clock.
  172. 0 = The FLEXCAN clock source is the chip Oscillator Clock.*/
  173. struct can_platform_data
  174. {
  175. unsigned int clock_src; /* FLEXCAN_CLKSRC_BUS or FLEXCAN_CLKSRC_XTAL */
  176. unsigned int clock_frq; /* can ref. clock, in Hz */
  177. };
  178. /*------------------------------ 全局变量 -------------------------------------
  179. */
  180. //flexcan设备
  181. static struct can_dev g_can_dev[CAN_BUS_NUM] __attribute__ ((aligned(4)));
  182. FN_CAN_RECV_CALLBACK g_can_recv_callback;
  183. u8 g_app_buf_tx[CAN_PRIO_MAX][CAN_FRAME_LEN_MAX]; //应用可根据优先级申请的长帧缓冲区
  184. extern int g_print_can;
  185. extern int g_print_can_monitor;
  186. /*------------------------------ 函数声明 -------------------------------------
  187. */
  188. static int _can_set_reset_mode(struct can_dev *dev);
  189. static int _can_set_normal_mode(struct can_dev *dev);
  190. static int _can_set_bittiming(struct can_dev *dev);
  191. static void _can_chipset_init(struct can_dev *dev, int clock_src);
  192. void _can_isr_0(void);
  193. void _can_isr_1(void);
  194. void _can_isr_err_0(void);
  195. void _can_isr_err_1(void);
  196. int _can_irq_force(int no);
  197. int _can_irq_clear(int no);
  198. int _can_irq_is_force(int no);
  199. /*------------------------------ 外部函数 -------------------------------------
  200. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  201. */
  202. int can_init(void)
  203. {
  204. struct can_dev *dev;
  205. int i;
  206. //初始化缓冲区
  207. memset(g_can_dev,0,sizeof(g_can_dev));
  208. for(i=0; i<CAN_BUS_NUM; i++)
  209. {
  210. dev = &g_can_dev[i];
  211. dev->no = i;
  212. if(i==0)
  213. {
  214. /* CAN0 */
  215. dev->base_addr = 0xFC020000;
  216. MCF_PMM_PPMCR0 = 8; /* enable FlexCAN0 clock */
  217. MCF_GPIO_PAR_CANI2C =
  218. (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SCL_MASK) |
  219. MCF_GPIO_PAR_CANI2C_I2C0SCL_CAN0TX;
  220. MCF_GPIO_PAR_CANI2C =
  221. (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SDA_MASK) |
  222. MCF_GPIO_PAR_CANI2C_I2C0SDA_CAN0RX;
  223. //设置驱动能力
  224. MCF_GPIO_SRCR_CANI2C=MCF_GPIO_SRCR_CANI2C | 0x03 ;
  225. }
  226. else
  227. {
  228. /* CAN1 */
  229. dev->base_addr = 0xFC024000;
  230. MCF_PMM_PPMCR0 = 9; /* enable FlexCAN1 clock */
  231. MCF_GPIO_PAR_CANI2C =
  232. (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_CAN1TX_MASK) |
  233. MCF_GPIO_PAR_CANI2C_CAN1TX_CAN1TX;
  234. MCF_GPIO_PAR_CANI2C =
  235. (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_CAN1RX_MASK) |
  236. MCF_GPIO_PAR_CANI2C_CAN1RX_CAN1RX;
  237. //设置驱动能力
  238. MCF_GPIO_SRCR_CANI2C=MCF_GPIO_SRCR_CANI2C | 0x0C ;
  239. }
  240. MCF_GPIO_PAR_CANI2C = 0x5f;
  241. /* set chip into reset mode */
  242. _can_set_reset_mode(dev);
  243. _can_set_bittiming(dev);
  244. // 申请实时中断
  245. if(i == 0)
  246. {
  247. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 0,CFG_INT_LEVEL_CAN,_can_isr_0,"can_isr_0");
  248. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 1,CFG_INT_LEVEL_CAN,_can_isr_err_0,"can_isr_err_00");
  249. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 3,CFG_INT_LEVEL_CAN,_can_isr_err_0,"can_isr_err_01");
  250. }
  251. else
  252. {
  253. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 4,CFG_INT_LEVEL_CAN,_can_isr_1,"can_isr_1");
  254. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 5,CFG_INT_LEVEL_CAN,_can_isr_err_1,"can_isr_err_10");
  255. rt_request_irq(CFG_CAN_VECTOR_BEGIN + 7,CFG_INT_LEVEL_CAN,_can_isr_err_1,"can_isr_err_11");
  256. }
  257. /* init and start flexcan */
  258. _can_chipset_init(dev, 0);
  259. _can_set_normal_mode(dev);
  260. }
  261. return 0;
  262. }
  263. int can_exit(void)
  264. {
  265. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 0);
  266. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 1);
  267. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 3);
  268. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 4);
  269. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 5);
  270. rt_free_irq(CFG_CAN_VECTOR_BEGIN + 7);
  271. return 0;
  272. }
  273. int can_regester_recv_callback(FN_CAN_RECV_CALLBACK fn)
  274. {
  275. g_can_recv_callback = fn;
  276. return 0;
  277. }
  278. u8 * can_request_tx_buf(u8 type)
  279. {
  280. int prior;
  281. //提取优先级
  282. prior=(type >> 6 ) & CAN_FRAME_MASK_PRIOR;
  283. return g_app_buf_tx[prior];
  284. }
  285. int can_send(u32 no,u8 *buf)
  286. {
  287. struct can_dev *dev;
  288. struct can_mb *pfm;
  289. int i,sf_num,sf_len ;
  290. int frame_mark; // 帧标识
  291. unsigned char prior; //应用优先级
  292. unsigned char *p;
  293. u32 len;
  294. // 检查参数
  295. if(no >= CAN_BUS_NUM)
  296. {
  297. return -1;
  298. }
  299. if(buf == NULL)
  300. {
  301. return -2;
  302. }
  303. // 检查地址
  304. if(buf[1]>= CAN_BUS_ADDR_NUM || buf[2] >= CAN_BUS_ADDR_NUM)
  305. {
  306. return -5;
  307. }
  308. // 检查长度
  309. len = buf[3];
  310. if(len > CAN_LONGFRAME_DATA_LEN)
  311. {
  312. return -6;
  313. }
  314. dev = &g_can_dev[no];
  315. //提取优先级
  316. prior=(buf[0] >> 6 ) & CAN_FRAME_MASK_PRIOR;
  317. // 将长帧转换为短帧
  318. //计算需要分为多少帧短帧
  319. sf_num=(len + CAN_FRAME_DATA_LEN - 1)/CAN_FRAME_DATA_LEN;
  320. if(sf_num == 0)
  321. {
  322. sf_num = 1;
  323. }
  324. //空间够吗?
  325. if(CAN_BUF_SPACE(&dev->tx_buf[prior], CAN_FRAME_NUM) < sf_num)
  326. {
  327. //发送溢出次数
  328. dev->stats.tx_dropped++;
  329. return -7;
  330. }
  331. // 打印报文
  332. if(g_print_can)
  333. {
  334. print_msg("TX_CAN:",buf,len+CAN_LONGFRAME_HEAD_LEN);
  335. }
  336. //帧序号递加
  337. dev->tx_buf[prior].frameno++;
  338. i=0;
  339. p= buf + CAN_LONGFRAME_HEAD_LEN;
  340. while(i<sf_num)
  341. {
  342. // 短帧数据长度
  343. sf_len = len>=CAN_FRAME_DATA_LEN?CAN_FRAME_DATA_LEN:len;
  344. // 帧标识
  345. if(sf_num == 1)
  346. {
  347. frame_mark = CAN_FRAME_SINGLE;
  348. }
  349. else
  350. {
  351. if(i == 0)
  352. {
  353. frame_mark = CAN_FRAME_BEGIN;
  354. }
  355. else if(i == (sf_num - 1))
  356. {
  357. frame_mark = CAN_FRAME_END ;
  358. }
  359. else
  360. {
  361. frame_mark = CAN_FRAME_MIDDLE;
  362. }
  363. }
  364. //指向当前头位置缓冲区
  365. pfm=(struct can_mb *)dev->tx_buf[prior].buf[dev->tx_buf[prior].head];
  366. //结构信息
  367. pfm->can_dlc=MB_CNT_CODE(0x08)|(1 << 21)|(1 << 22)|(sf_len << 16) ;
  368. // 帧ID
  369. pfm->can_id= (buf[0] << CAN_FRAME_OFFSET_TYPE)
  370. | (buf[1] << CAN_FRAME_OFFSET_DST)
  371. | (buf[2] << CAN_FRAME_OFFSET_SRC)
  372. | (frame_mark << CAN_FRAME_OFFSET_MARK)
  373. | (dev->tx_buf[prior].frameno & CAN_FRAME_MASK_SN);
  374. // 数据
  375. memcpy(pfm->data, p, sf_len);
  376. len -= sf_len; //剩余多少数据
  377. p += sf_len; //调整数据指针
  378. //头下标往后移
  379. dev->tx_buf[prior].head++;
  380. //下一短帧
  381. i++;
  382. }
  383. //统计发送长帧
  384. dev->stats.tx_longframes++;
  385. // 启动发送
  386. _can_irq_force(no);
  387. return (buf[3] + CAN_LONGFRAME_HEAD_LEN);
  388. }
  389. int can_recv(u32 no,u8 *buf,u32 len)
  390. {
  391. struct can_dev *dev;
  392. int i;
  393. int framelen;
  394. // 检查参数
  395. if(no >= CAN_BUS_NUM)
  396. {
  397. return -1;
  398. }
  399. if(buf == NULL)
  400. {
  401. return -2;
  402. }
  403. dev = &g_can_dev[no];
  404. //从0优先级开始,读取接收缓冲区的数据
  405. for(i=0;i<CAN_PRIO_MAX;i++)
  406. {
  407. //对应的长帧缓冲区没有长帧
  408. if(CAN_BUF_EMPTY(&dev->longframe_buf_rx[i]))
  409. continue;
  410. //长帧长度
  411. framelen=dev->longframe_buf_rx[i].buf[dev->longframe_buf_rx[i].tail][CAN_LONGFRAME_HEAD_LEN - 1] + CAN_LONGFRAME_HEAD_LEN;
  412. //拷贝数据到用户空间
  413. if(framelen <= len)
  414. {
  415. memcpy(buf, dev->longframe_buf_rx[i].buf[dev->longframe_buf_rx[i].tail], framelen);
  416. //调整尾位置
  417. dev->longframe_buf_rx[i].tail = (dev->longframe_buf_rx[i].tail+1) & (CAN_LONGFRAME_NUM-1);
  418. }
  419. else
  420. {
  421. rt_printf("can_recv:framelen=%d, len=%d\r\n",framelen,len);
  422. framelen=-3;
  423. }
  424. return framelen;
  425. }
  426. return 0;
  427. }
  428. int can_stat(void)
  429. {
  430. int i=0;
  431. rt_printf("flexcan communicate stat\r\n");
  432. for(i=0;i<CAN_BUS_NUM;i++)
  433. {
  434. rt_printf("flexcan%d:\r\n",i);
  435. rt_printf("tx_longframes:\t%u\r\n",g_can_dev[i].stats.tx_longframes);
  436. rt_printf("rx_longframes:\t%u\r\n",g_can_dev[i].stats.rx_longframes);
  437. rt_printf("tx_shortframes:\t%u\r\n",g_can_dev[i].stats.tx_shortframes);
  438. rt_printf("rx_shortframes:\t%u\r\n",g_can_dev[i].stats.rx_shortframes);
  439. rt_printf("tx_dropped:\t%u\r\n",g_can_dev[i].stats.tx_dropped);
  440. rt_printf("rx_dropped:\t%u\r\n",g_can_dev[i].stats.rx_dropped);
  441. rt_printf("hw_bus_errors:\t%u\r\n",g_can_dev[i].stats.hw_bus_errors);
  442. rt_printf("overrun:\t%u\r\n",g_can_dev[i].stats.overrun);
  443. }
  444. return 0;
  445. }
  446. int can_stat_reset(void)
  447. {
  448. int i=0;
  449. for(i=0;i<CAN_BUS_NUM;i++)
  450. {
  451. memset(&g_can_dev[i].stats,0,sizeof(g_can_dev[i].stats));
  452. }
  453. return 0;
  454. }
  455. /*------------------------------ 内部函数 -------------------------------------
  456. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  457. */
  458. /******************************************************************************
  459. 函数名称: _can_set_reset_mode
  460. 函数版本: 01.01
  461. 创建作者: xxxxxx
  462. 创建日期: 2010-09-25
  463. 函数说明: 复位FLEXCAN
  464. 参数说明:
  465. dev: flexcan 设备
  466. 返回值:成功返回0,失败返回1
  467. 修改记录:
  468. */
  469. static int _can_set_reset_mode(struct can_dev *dev)
  470. {
  471. volatile struct can_regs *regs = \
  472. (volatile struct can_regs *)dev->base_addr;
  473. int i;
  474. /* disable all MB interrupts */
  475. regs->canimask = IMASK_BUFF_DISABLE_ALL;
  476. /* disable error and bus off interrupt */
  477. regs->canctrl &= ~(CANCTRL_ERRMSK | CANCTRL_BOFFMSK);
  478. /* reset chip */
  479. regs->canmcr &= ~(CANMCR_MDIS);
  480. regs->canmcr |= CANMCR_SOFTRST;
  481. for (i = 0; i < FLEXCAN_SET_MODE_RETRIES; i++) {
  482. /* check reset bit */
  483. if ((regs->canmcr & CANMCR_SOFTRST) == 0x00) {
  484. //priv->can.state = CAN_STATE_STOPPED;
  485. return 0;
  486. }
  487. ustimer_delay(10*USTIMER_US);
  488. }
  489. return 1;
  490. }
  491. /******************************************************************************
  492. 函数名称: _can_set_normal_mode
  493. 函数版本: 01.01
  494. 创建作者: xxxxxx
  495. 创建日期: 2010-09-25
  496. 函数说明: 设置正常模式
  497. 参数说明:
  498. dev: flexcan 设备
  499. 返回值:成功返回0,失败返回1
  500. 修改记录:
  501. */
  502. static int _can_set_normal_mode(struct can_dev *dev)
  503. {
  504. volatile struct can_regs *regs = \
  505. (volatile struct can_regs *)dev->base_addr;
  506. int i;
  507. // 模式寄存器配置
  508. // regs->canmcr |= CANMCR_SRXDIS; // 禁止自接收(如果允许监视所有短帧,必须允许自接收)
  509. regs->canmcr |= CANMCR_WARN_EN; // 允许告警
  510. regs->canmcr |= CANMCR_FEN; // 允许接收FIFO
  511. /* enable the module */
  512. regs->canmcr &= ~CANMCR_MDIS;
  513. /* synchronize with can bus*/
  514. regs->canmcr &= ~CANMCR_HALT;
  515. for (i = 0; i < FLEXCAN_SET_MODE_RETRIES; i++)
  516. {
  517. /* check freeze and disabled bit */
  518. if (!(regs->canmcr & (CANMCR_NOTRDY | CANMCR_FRZACK)))
  519. {
  520. /* enable all MB interrupts */
  521. regs->canimask = IMASK_BUFF_ENABLE_ALL;
  522. /* Enable error and bus off interrupt */
  523. // regs->canctrl |= (CANCTRL_ERRMSK | CANCTRL_BOFFMSK);
  524. regs->canctrl |= (CANCTRL_TWRN_MSK | CANCTRL_RWRN_MSK | CANCTRL_BOFFMSK);
  525. return 0;
  526. }
  527. ustimer_delay(10*USTIMER_US);
  528. }
  529. return 1;
  530. }
  531. /******************************************************************************
  532. 函数名称: _can_set_bittiming
  533. 函数版本: 01.01
  534. 创建作者: xxxxxx
  535. 创建日期: 2010-09-25
  536. 函数说明: 波特率设置函数
  537. 使用外部晶振50M
  538. 配置为500K:
  539. reg = CANCTRL_PRESDIV(9) | CANCTRL_RJW(0);
  540. reg |= (CANCTRL_PROPSEG(2) |
  541. CANCTRL_PSEG1(3) |
  542. CANCTRL_PSEG2(1) |
  543. CANCTRL_SAMP(0));
  544. regs->canctrl |= reg;
  545. 配置为1M:
  546. reg = CANCTRL_PRESDIV(4) | CANCTRL_RJW(0);
  547. reg |= (CANCTRL_PROPSEG(3) |
  548. CANCTRL_PSEG1(2) |
  549. CANCTRL_PSEG2(1) |
  550. CANCTRL_SAMP(0));
  551. regs->canctrl |= reg;
  552. 参数说明:
  553. dev: flexcan 设备
  554. 返回值: 返回0
  555. 修改记录:
  556. */
  557. static int _can_set_bittiming(struct can_dev *dev)
  558. {
  559. volatile struct can_regs *regs = \
  560. (struct can_regs *)dev->base_addr;
  561. volatile u32 reg = 0;
  562. /* Clear the old bittiming */
  563. reg = CANCTRL_PRESDIV(0xFF) | CANCTRL_RJW(0x03);
  564. reg |= (CANCTRL_PROPSEG(0x07) |
  565. CANCTRL_PSEG1(0x07) |
  566. CANCTRL_PSEG2(0x07) |
  567. CANCTRL_SAMP(0x01));
  568. regs->canctrl &= ~reg;
  569. //配置波特率为1M
  570. reg = CANCTRL_PRESDIV(4) | CANCTRL_RJW(0);
  571. reg |= (CANCTRL_PROPSEG(3) |
  572. CANCTRL_PSEG1(2) |
  573. CANCTRL_PSEG2(1) |
  574. CANCTRL_SAMP(0));
  575. regs->canctrl |= reg;
  576. return 0;
  577. }
  578. /******************************************************************************
  579. 函数名称: _can_chipset_init
  580. 函数版本: 01.01
  581. 创建作者: xxxxxx
  582. 创建日期: 2010-09-25
  583. 函数说明: 初始化flexcan
  584. 参数说明:
  585. dev: flexcan 设备
  586. clock_src: 时钟源,0表示外部晶振,1表示内部总线时钟
  587. 返回值:
  588. 修改记录:
  589. */
  590. /*
  591. * initialize flexcan:
  592. * - set clock source
  593. * - set output mode
  594. * - set baudrate
  595. * - enable interrupts
  596. * - start operating mode
  597. */
  598. static void _can_chipset_init(struct can_dev *dev, int clock_src)
  599. {
  600. volatile struct can_regs *regs = \
  601. (volatile struct can_regs *)dev->base_addr;
  602. int i, j;
  603. /* Setting the Clk */
  604. if (clock_src)
  605. regs->canctrl |= CANCTRL_CLKSRC;
  606. else
  607. regs->canctrl &= ~CANCTRL_CLKSRC;
  608. /* set LBUF to sending from lower buffer*/
  609. regs->canctrl |= CANCTRL_LBUF;
  610. // 初始化消息buf
  611. for (i = 0; i < CAN_MB; i++)
  612. {
  613. regs->cantxfg[i].can_dlc = 0;
  614. regs->cantxfg[i].can_id = 0;
  615. for (j = 0; j < 8; j++)
  616. regs->cantxfg[i].data[j] = 0;
  617. }
  618. //使用各自独立的报文过滤
  619. regs->canmcr |= CANMCR_BCC;
  620. for (i = 0; i < CAN_MB; i++)
  621. {
  622. //不过滤报文
  623. regs->rximr[i]=0x00000000;
  624. }
  625. //闭环模式
  626. #if 0
  627. regs->canctrl |= CANCTRL_LPB;
  628. #else
  629. regs->canctrl &= ~CANCTRL_LPB;
  630. #endif
  631. }
  632. /******************************************************************************
  633. 函数名称: _can_int_tx
  634. 函数版本: 01.01
  635. 创建作者: xxxxxx
  636. 创建日期: 2010-09-25
  637. 函数说明: flexcan发送处理
  638. 参数说明:
  639. dev: flexcan 设备
  640. 返回值:
  641. 修改记录:
  642. */
  643. static void _can_int_tx(struct can_dev *dev)
  644. {
  645. int i=0;
  646. struct can_mb *pfm;
  647. int txbuf = SEND_BUF;
  648. volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
  649. for(i=0;i<CAN_PRIO_MAX;i++)
  650. {
  651. int j=0;
  652. unsigned int code=0;
  653. //对应优先级的缓冲区是否有数据
  654. if(CAN_BUF_EMPTY(&dev->tx_buf[i]))
  655. {
  656. continue;
  657. }
  658. //当前位置的缓冲区
  659. pfm=(struct can_mb *)dev->tx_buf[i].buf[dev->tx_buf[i].tail];
  660. //检查是否可以发送. code==8说明上一次成功发送完毕,code==0是第一次将CODE配置0了即是MB_CNT_CODE(0)
  661. code= (regs->cantxfg[txbuf].can_dlc >> 24) & 0x0F;
  662. if(!((code==8) || (code==0)))
  663. {
  664. //rt_printf("bus is busy\r\n");
  665. break;
  666. }
  667. //写数据到寄存器
  668. regs->cantxfg[txbuf].can_dlc=pfm->can_dlc;
  669. regs->cantxfg[txbuf].can_id=pfm->can_id;
  670. for(j=0;j<8;j++)
  671. {
  672. regs->cantxfg[txbuf].data[j]=pfm->data[j];
  673. }
  674. /*Control/status word to hold Tx MB active */
  675. regs->cantxfg[txbuf].can_dlc |= MB_CNT_CODE(0x0c);
  676. //调整尾指针
  677. dev->tx_buf[i].tail++;
  678. //统计发送短帧总数加一
  679. dev->stats.tx_shortframes++;
  680. break;
  681. }
  682. }
  683. /******************************************************************************
  684. 函数名称: _can_frame_short2long
  685. 函数版本: 01.01
  686. 创建作者: xxxxxx
  687. 创建日期: 2010-09-25
  688. 函数说明: 短帧组长帧
  689. 参数说明:
  690. dev: flexcan 设备
  691. prior: 优先级
  692. 返回值:
  693. 修改记录:
  694. */
  695. static int _can_frame_short2long(struct can_dev *dev, int prior)
  696. {
  697. static unsigned char pos_rec[CAN_FRAME_NUM];
  698. int pos_index;
  699. int i,len,is_deal;
  700. struct can_mb *pfm;
  701. struct can_mb *pfmtmp;
  702. unsigned char *pd,*p;
  703. unsigned char tmppos=dev->rx_buf[prior].head-1;
  704. unsigned char srcaddr;
  705. unsigned char dstaddr;
  706. unsigned char frameno;
  707. unsigned char frame_type;
  708. unsigned char frame_len;
  709. unsigned int frame_mark;
  710. unsigned char srcaddrtmp;
  711. unsigned char dstaddrtmp;
  712. unsigned char framenotmp;
  713. unsigned char frame_type_tmp;
  714. //结束帧指针
  715. pfm=(struct can_mb *)dev->rx_buf[prior].buf[tmppos];
  716. srcaddr=(pfm->can_id >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
  717. dstaddr=(pfm->can_id >> CAN_FRAME_OFFSET_DST) & CAN_FRAME_MASK_DST;
  718. frameno=pfm->can_id & CAN_FRAME_MASK_SN;
  719. frame_type=(unsigned char)(pfm->can_id >> CAN_FRAME_OFFSET_TYPE) & CAN_FRAME_MASK_TYPE;
  720. frame_len = (pfm->can_dlc >> CAN_FRAME_OFFSET_LEN) & CAN_FRAME_MASK_LEN;
  721. // 查找起始帧
  722. pos_index = 0;
  723. for(i=0;i<CAN_FRAME_NUM;i++)
  724. {
  725. // 短帧
  726. pfmtmp=(struct can_mb *)dev->rx_buf[prior].buf[tmppos];
  727. frame_mark = (pfmtmp->can_id >> CAN_FRAME_OFFSET_MARK)& CAN_FRAME_MASK_MARK;
  728. srcaddrtmp = (pfmtmp->can_id >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
  729. dstaddrtmp = (pfmtmp->can_id >> CAN_FRAME_OFFSET_DST) & CAN_FRAME_MASK_DST;
  730. framenotmp = pfmtmp->can_id & CAN_FRAME_MASK_SN;
  731. frame_type_tmp = (unsigned char)(pfmtmp->can_id >> CAN_FRAME_OFFSET_TYPE) & CAN_FRAME_MASK_TYPE;
  732. // 是要找的短帧
  733. if((srcaddr == srcaddrtmp ) && ( dstaddr==dstaddrtmp) && (frameno==framenotmp) && (frame_type == frame_type_tmp))
  734. {
  735. // 记录短帧位置
  736. pos_rec[pos_index++] = tmppos;
  737. // 找到起始帧
  738. if((frame_mark == CAN_FRAME_BEGIN) || (frame_mark == CAN_FRAME_SINGLE) )
  739. {
  740. break;
  741. }
  742. }
  743. // 前一短帧
  744. tmppos--;
  745. }
  746. if(pos_index == 0)
  747. {
  748. rt_printf("_can_frame_short2long:pos_index=%d\r\n",pos_index);
  749. dev->stats.rx_dropped++;
  750. return -1;
  751. }
  752. if(i == CAN_FRAME_NUM)
  753. {
  754. #if 0
  755. rt_printf("_can_frame_short2long:i=%d,pos_index=%d.\r\n",i,pos_index);
  756. #endif
  757. dev->stats.rx_dropped++;
  758. return -11;
  759. }
  760. // 检查长度
  761. len = frame_len + (pos_index - 1)*CAN_FRAME_DATA_LEN;
  762. if(len > CAN_LONGFRAME_DATA_LEN)
  763. {
  764. rt_printf("_can_frame_short2long:i=%d\r\n",i);
  765. dev->stats.rx_dropped++;
  766. return -2;
  767. }
  768. //长帧缓冲区首指针
  769. pd=dev->longframe_buf_rx[prior].buf[dev->longframe_buf_rx[prior].head];
  770. p = pd;
  771. // 长帧头
  772. p[0] = (pfmtmp->can_id >> CAN_FRAME_OFFSET_TYPE);
  773. p[1] = dstaddrtmp;
  774. p[2] = srcaddrtmp;
  775. p[3] = len;
  776. // 长帧数据
  777. p += CAN_LONGFRAME_HEAD_LEN;
  778. while(pos_index--)
  779. {
  780. len = pos_index == 0 ? frame_len : 8;
  781. pfmtmp=(struct can_mb *)dev->rx_buf[prior].buf[pos_rec[pos_index]];
  782. memcpy(p, pfmtmp->data, len);
  783. // 置帧空标志
  784. pfmtmp->can_dlc = 0;
  785. p+=8;
  786. }
  787. // 打印报文
  788. if(g_print_can)
  789. {
  790. print_msg("RX_CAN:",pd,pd[3] + CAN_LONGFRAME_HEAD_LEN);
  791. }
  792. // 回调处理此长帧
  793. is_deal = 0;
  794. if(g_can_recv_callback)
  795. {
  796. is_deal = g_can_recv_callback(dev->no,pd);
  797. }
  798. // 如果此长帧没有处理,调整头位置
  799. if(is_deal != 1)
  800. {
  801. if(CAN_BUF_SPACE(&dev->longframe_buf_rx[prior], CAN_LONGFRAME_NUM) == 0)
  802. {
  803. dev->stats.rx_dropped++;
  804. rt_printf("长帧溢出\r\n");
  805. }
  806. else
  807. {
  808. dev->longframe_buf_rx[prior].head=(dev->longframe_buf_rx[prior].head+1) & (CAN_LONGFRAME_NUM-1);
  809. }
  810. // 唤醒主循环处理此长帧
  811. mainloop_wakeup();
  812. }
  813. return 0;
  814. }
  815. /******************************************************************************
  816. 函数名称: _can_int_rx
  817. 函数版本: 01.01
  818. 创建作者: xxxxxx
  819. 创建日期: 2010-09-25
  820. 函数说明: flexcan接收中断处理
  821. 参数说明:
  822. dev: flexcan 设备
  823. i: 表示第几个接收MB
  824. 返回值:
  825. 修改记录:
  826. */
  827. void _can_bus_monitor(u8 *buf)
  828. {
  829. static s8 str[128];
  830. s8 *p;
  831. int i;
  832. sprintf(str,"CAN_RS:");
  833. p = str + 7;
  834. for(i=0;i<16;i++)
  835. {
  836. sprintf(p,"%02x ",buf[i]);
  837. p += 3;
  838. }
  839. sprintf(p,"\r\n");
  840. rt_printf(str);
  841. }
  842. static void _can_int_rx(struct can_dev *dev, int i)
  843. {
  844. volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
  845. struct can_mb *mb = (struct can_mb *)&regs->cantxfg[i];
  846. struct can_mb *pfm;
  847. int ctrl = mb->can_dlc;
  848. int canid=mb->can_id;
  849. u32 prior=(canid >> CAN_FRAME_OFFSET_PRIOR) & 0x03;
  850. u32 srcaddr = (canid >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
  851. int k;
  852. // 取短帧BUF
  853. pfm=(struct can_mb *)dev->rx_buf[prior].buf[dev->rx_buf[prior].head];
  854. if(pfm->can_dlc)
  855. {
  856. #if 0
  857. print_mem("CAN_BUF_FULL: ",(u8*)pfm,16);
  858. #endif
  859. dev->stats.overrun++;
  860. }
  861. // 得到内容
  862. pfm->can_dlc = ctrl;
  863. pfm->can_id = mb->can_id;
  864. for (k = 0; k < 8; k++)
  865. pfm->data[k] =\
  866. regs->cantxfg[i].data[k];
  867. // 如果总线监视,打印短帧
  868. if(g_print_can_monitor)
  869. {
  870. _can_bus_monitor((u8*)pfm);
  871. }
  872. // 如果是自己发送的帧,直接返回
  873. if(srcaddr == 0)
  874. {
  875. // 置帧空标志
  876. pfm->can_dlc = 0;
  877. return;
  878. }
  879. //统计接收短帧总数
  880. dev->stats.rx_shortframes++;
  881. //调整当前位置
  882. dev->rx_buf[prior].head++;
  883. //是结束帧就开始组长帧
  884. if(((canid >> CAN_FRAME_OFFSET_MARK) & CAN_FRAME_MASK_MARK) < 0x02)
  885. {
  886. //统计接收长帧总数
  887. dev->stats.rx_longframes++;
  888. //短帧组长帧
  889. _can_frame_short2long(dev, prior);
  890. }
  891. }
  892. void _can_isr(int no)
  893. {
  894. struct can_dev *dev = &g_can_dev[no];
  895. volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
  896. u32 oflags;
  897. // 得到中断标志
  898. oflags = regs->caniflg;
  899. // 处理发送软中断
  900. if(_can_irq_is_force(no))
  901. {
  902. // 应用程序启动发送
  903. oflags |= SEND_BUF_BIT;
  904. _can_irq_clear(no);
  905. }
  906. // 检查发送标志
  907. if(oflags & SEND_BUF_BIT)
  908. {
  909. // 清发送中断
  910. regs->caniflg = SEND_BUF_BIT;
  911. oflags &= (~SEND_BUF_BIT);
  912. // 发送一帧
  913. _can_int_tx(dev);
  914. }
  915. // 处理接收中断
  916. // 硬件overrun
  917. if(oflags & 0x80)
  918. {
  919. dev->stats.overrun++;
  920. }
  921. // 接收一帧
  922. if(oflags & 0x20)
  923. {
  924. _can_int_rx(dev,0);
  925. }
  926. // 清接收中断标志
  927. regs->caniflg = oflags;
  928. return ;
  929. }
  930. void _can_isr_err(int no)
  931. {
  932. struct can_dev *dev = &g_can_dev[no];
  933. volatile struct can_regs *regs = (struct can_regs *)dev->base_addr;
  934. u32 errstate = regs->canerrstat;
  935. regs->canerrstat = errstate;
  936. dev->stats.hw_bus_errors++;//统计出错信息
  937. return ;
  938. }
  939. void _can_isr_0(void)
  940. {
  941. _can_isr(0);
  942. }
  943. void _can_isr_1(void)
  944. {
  945. _can_isr(1);
  946. }
  947. void _can_isr_err_0(void)
  948. {
  949. _can_isr_err(0);
  950. }
  951. void _can_isr_err_1(void)
  952. {
  953. _can_isr_err(1);
  954. }
  955. int _can_irq_force(int no)
  956. {
  957. uint32_t flags;
  958. no *= 4;
  959. rt_irq_save(flags);
  960. REG_MCF_INTFRCL1 |= 1 << no;
  961. rt_irq_restore(flags);
  962. return 0;
  963. }
  964. int _can_irq_clear(int no)
  965. {
  966. uint32_t flags;
  967. no *= 4;
  968. rt_irq_save(flags);
  969. REG_MCF_INTFRCL1 &= ~(1 << no);
  970. rt_irq_restore(flags);
  971. return 0;
  972. }
  973. int _can_irq_is_force(int no)
  974. {
  975. no *= 4;
  976. if(REG_MCF_INTFRCL1 & (1 << no))
  977. {
  978. return 1;
  979. }
  980. else
  981. {
  982. return 0;
  983. }
  984. }
  985. /*------------------------------ 测试函数 -------------------------------------
  986. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  987. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  988. */
  989. #define LOOP_BEGIN 1
  990. int can_test(void)
  991. {
  992. static unsigned char buf_tx[CAN_LONGFRAME_LEN],buf_rx[CAN_LONGFRAME_LEN];
  993. static unsigned char loop = LOOP_BEGIN;
  994. static uint32_t us0 = 0,err_count=0;
  995. uint32_t us1;
  996. int i;
  997. int len_tx,len_rx;
  998. // 1S调用一次
  999. us1 = ustimer_get_origin();
  1000. if(us1 - us0 < USTIMER_SEC*10)
  1001. {
  1002. return 0;
  1003. }
  1004. us0 = us1;
  1005. // 发送一帧
  1006. memset(buf_tx,0,sizeof(buf_tx));
  1007. buf_tx[0] = loop;
  1008. buf_tx[1] = 1;
  1009. buf_tx[2] = 2;
  1010. buf_tx[3] = loop;
  1011. for(i=0; i<buf_tx[3]; i++)
  1012. {
  1013. buf_tx[CAN_LONGFRAME_HEAD_LEN + i] = i;
  1014. }
  1015. len_tx = can_send(0,buf_tx);
  1016. // len_tx = can_send(1,buf_tx);
  1017. // 延时5ms
  1018. ustimer_delay(USTIMER_MS*50);
  1019. // 接收一帧
  1020. memset(buf_rx,0,sizeof(buf_rx));
  1021. len_rx = can_recv(0,buf_rx,256);
  1022. if((len_tx == len_rx) && (memcmp(buf_tx,buf_rx,len_tx) == 0))
  1023. {
  1024. rt_printf("can_test ok(%03d,err_count=%d):[len_tx=%d,len_rx=%d]\r\n",loop,err_count,len_tx,len_rx);
  1025. }
  1026. else
  1027. {
  1028. err_count++;
  1029. rt_printf("can_test err(%03d,err_count=%d):[len_tx=%d,len_rx=%d]\r\n",loop,err_count,len_tx,len_rx);
  1030. // can_print_mem("TX:",buf_tx,len_tx);
  1031. // can_print_mem("RX:",buf_rx,len_rx);
  1032. }
  1033. // loop++;
  1034. if(loop > CAN_LONGFRAME_DATA_LEN)
  1035. {
  1036. loop = LOOP_BEGIN;
  1037. }
  1038. return 0;
  1039. }
  1040. #endif
  1041. /*------------------------------ 文件结束 -------------------------------------
  1042. */