drv_can.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. #include "common.h"
  2. #include "drv_can.h"
  3. #include "drv_io.h"
  4. extern uint8_t work_normal;
  5. //********************************************************CAN-START**********************************************************
  6. static uint8_t can_rx_ctr_self_buf[CAN_RX_BUF_MAX];
  7. static uint8_t can_rx_ctr_bro_buf[CAN_RX_CTR_BRO_BUF_MAX];
  8. static uint8_t can_rx_test_bro_buf[CAN_RX_TEST_BRO_BUF_MAX];
  9. can_parameter_struct can_parameter;
  10. can_filter_parameter_struct can_filter;
  11. #define CAN_BAUDRATE 250
  12. uint32_t filter_ctr_self_id = (CTR_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
  13. uint32_t filter_ctr_bro_id = (CTR_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
  14. #ifdef CONFIG_CAN_IAP
  15. uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
  16. #else
  17. uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
  18. #endif
  19. CAN_FRAME can_ctr_self;
  20. CAN_FRAME can_ctr_bro;
  21. CAN_FRAME can_test_bro;
  22. static shark_can_frame_t shark_can_tx_queue[200];
  23. static shark_u8 shark_can_tx_head;
  24. static shark_u8 shark_can_tx_tail;
  25. static shark_u16 shark_can_tx_err;
  26. static shark_bool shark_can_tx_frame(shark_can_frame_t *frame)
  27. {
  28. u8 mailbox;
  29. if (CAN_TSTAT_TME0 == (CAN_TSTAT(CAN0) & CAN_TSTAT_TME0)) {
  30. mailbox = CAN_MAILBOX0;
  31. } else if (CAN_TSTAT_TME1 == (CAN_TSTAT(CAN0) & CAN_TSTAT_TME1)) {
  32. mailbox = CAN_MAILBOX1;
  33. } else if (CAN_TSTAT_TME2 == (CAN_TSTAT(CAN0) & CAN_TSTAT_TME2)) {
  34. mailbox = CAN_MAILBOX2;
  35. } else {
  36. if (work_normal == 0) {
  37. return shark_true;
  38. }
  39. if (shark_can_tx_err < 20000) {
  40. shark_can_tx_err++;
  41. } else {
  42. shark_can_tx_err = 0;
  43. can_deinit(CAN0);
  44. CAN_Config_HW();
  45. }
  46. return shark_false;
  47. }
  48. shark_can_tx_err = 0;
  49. CAN_TMDATA0(CAN0, mailbox) = frame->values[0];
  50. CAN_TMDATA1(CAN0, mailbox) = frame->values[1];
  51. CAN_TMP(CAN0, mailbox) &= ~CAN_TMP_DLENC;
  52. CAN_TMP(CAN0, mailbox) |= frame->efid.length + 1;
  53. CAN_TMI(CAN0, mailbox) = frame->efid.value << 3 | CAN_FF_EXTENDED | CAN_FT_DATA | CAN_TMI_TEN;
  54. return shark_true;
  55. }
  56. void shark_can_tx_flush(void)
  57. {
  58. while (shark_can_tx_head != shark_can_tx_tail && shark_can_tx_frame(shark_can_tx_queue + shark_can_tx_head)) {
  59. shark_can_tx_head = (shark_can_tx_head + 1) % NELEM(shark_can_tx_queue);
  60. }
  61. }
  62. shark_bool shark_can_send_frame(shark_can_efid_t efid, const void *buff, u8 length)
  63. {
  64. u8 tail = (shark_can_tx_tail + 1) % NELEM(shark_can_tx_queue);
  65. shark_can_frame_t *frame;
  66. shark_can_tx_flush();
  67. if (tail == shark_can_tx_head || work_normal == 0) {
  68. return shark_false;
  69. }
  70. frame = shark_can_tx_queue + shark_can_tx_tail;
  71. memcpy(frame->data, buff, length);
  72. frame->efid.value = efid.value;
  73. if (shark_can_tx_tail == shark_can_tx_head && shark_can_tx_frame(frame)) {
  74. return shark_true;
  75. }
  76. shark_can_tx_tail = tail;
  77. return shark_true;
  78. }
  79. shark_bool shark_can_send(u8 dest, u8 src, u8 type, const u8 *buff, u16 length)
  80. {
  81. shark_can_efid_t efid;
  82. u8 index = 1;
  83. efid.dest = dest;
  84. efid.src = src;
  85. efid.type = type;
  86. efid.priority = 6;
  87. efid.total = (length + 7) / 8;
  88. while (length > 0) {
  89. u8 wrlen = length < 8 ? length : 8;
  90. efid.index = index;
  91. efid.length = wrlen - 1;
  92. if (shark_can_send_frame(efid, buff, wrlen)) {
  93. length -= wrlen;
  94. buff += wrlen;
  95. index++;
  96. } else {
  97. return shark_false;
  98. }
  99. }
  100. return shark_true;
  101. }
  102. void Can_Stop_Send(void)
  103. {
  104. shark_can_tx_head = shark_can_tx_tail = 0;
  105. }
  106. int8_t Send_Data_Can(CAN_FRAME*app_can_frame,uint8_t from)
  107. {
  108. return shark_can_send(app_can_frame->head.dest, app_can_frame->head.sour, app_can_frame->head.rsp, app_can_frame->data, app_can_frame->len);
  109. }
  110. void Check_Can_Poll(void)
  111. {
  112. if(work_normal)
  113. {
  114. if(can_error_get(CAN0) != CAN_ERROR_NONE)
  115. {
  116. Can_Power_Enable(0);
  117. can_deinit(CAN0);
  118. CAN_Config_HW();
  119. Can_Power_Enable(1);
  120. }
  121. }
  122. }
  123. static void Reset_Can_Rx_Buffer(CAN_FRAME*can_frame)
  124. {
  125. if(can_frame == NULL)
  126. return;
  127. memset(&can_frame->head,0x00,sizeof(can_frame->head));
  128. can_frame->len = 0;
  129. }
  130. uint16_t Get_Data_Can(CAN_FRAME*app_can_frame)
  131. {
  132. CAN_FRAME* cf_temp = NULL;
  133. if(app_can_frame == NULL)
  134. return 0;
  135. if(get_index_total_value(can_ctr_self.head.index) != 0 && can_ctr_self.head.index == can_ctr_self.head.total&&can_ctr_self.len)
  136. cf_temp = &can_ctr_self;
  137. else if(get_index_total_value(can_ctr_bro.head.index) != 0 && can_ctr_bro.head.index == can_ctr_bro.head.total&&can_ctr_bro.len)
  138. cf_temp = &can_ctr_bro;
  139. else if(get_index_total_value(can_test_bro.head.index) != 0 && can_test_bro.head.index == can_test_bro.head.total&&can_test_bro.len)
  140. cf_temp = &can_test_bro;
  141. if(cf_temp == NULL)
  142. return 0;
  143. memcpy(&app_can_frame->head,&cf_temp->head,sizeof(cf_temp->head));
  144. memcpy(app_can_frame->data,cf_temp->data,cf_temp->len);
  145. app_can_frame->len = cf_temp->len;
  146. Reset_Can_Rx_Buffer(cf_temp);
  147. return app_can_frame->len;
  148. }
  149. static void Can_NVIC_Config(void)
  150. {
  151. // nvic_irq_enable(USBD_HP_CAN0_TX_IRQn,3,0);
  152. nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn,3,0);
  153. }
  154. /**
  155. * @brief Configures the CAN.
  156. * @param None
  157. * @retval None
  158. */
  159. void CAN_Config_HW(void)
  160. {
  161. /* enable CAN clock */
  162. rcu_periph_clock_enable(RCU_CAN0);
  163. rcu_periph_clock_enable(RCU_GPIOB);
  164. rcu_periph_clock_enable(RCU_AF);
  165. /* configure CAN0 GPIO */
  166. gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
  167. gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
  168. gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
  169. rcu_periph_clock_enable(RCU_GPIOA);
  170. gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
  171. Silent_Enable(0);
  172. can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
  173. can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
  174. /* initialize CAN register */
  175. can_deinit(CAN0);
  176. /* initialize CAN parameters */
  177. can_parameter.time_triggered = DISABLE;
  178. can_parameter.auto_bus_off_recovery = DISABLE;
  179. can_parameter.auto_wake_up = DISABLE;
  180. can_parameter.auto_retrans = DISABLE;
  181. can_parameter.rec_fifo_overwrite = DISABLE;
  182. can_parameter.trans_fifo_order = ENABLE;
  183. can_parameter.working_mode = CAN_NORMAL_MODE;
  184. can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
  185. can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
  186. can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
  187. /* 1MBps */
  188. #if CAN_BAUDRATE == 1000
  189. can_parameter.prescaler = 6;
  190. /* 500KBps */
  191. #elif CAN_BAUDRATE == 500
  192. can_parameter.prescaler = 12;
  193. /* 250KBps */
  194. #elif CAN_BAUDRATE == 250
  195. can_parameter.prescaler = 24;
  196. /* 125KBps */
  197. #elif CAN_BAUDRATE == 125
  198. can_parameter.prescaler = 48;
  199. /* 100KBps */
  200. #elif CAN_BAUDRATE == 100
  201. can_parameter.prescaler = 60;
  202. /* 50KBps */
  203. #elif CAN_BAUDRATE == 50
  204. can_parameter.prescaler = 120;
  205. /* 20KBps */
  206. #elif CAN_BAUDRATE == 20
  207. can_parameter.prescaler = 300;
  208. #else
  209. #error "please select list can baudrate in private defines in drv_can.c "
  210. #endif
  211. /* initialize CAN */
  212. can_init(CAN0, &can_parameter);
  213. /* initialize filter */
  214. can_filter.filter_number=0;
  215. can_filter.filter_mode = CAN_FILTERMODE_MASK;
  216. can_filter.filter_bits = CAN_FILTERBITS_32BIT;
  217. #if 1
  218. can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16);
  219. can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0);
  220. can_filter.filter_mask_high = 0x0001;
  221. can_filter.filter_mask_low = 0xFFFF;
  222. #else
  223. can_filter.filter_list_high = 0x0000;
  224. can_filter.filter_list_low = 0x0000;
  225. can_filter.filter_mask_high = 0x0000;
  226. can_filter.filter_mask_low = 0x0000;
  227. #endif
  228. can_filter.filter_fifo_number = CAN_FIFO0;
  229. can_filter.filter_enable = ENABLE;
  230. can_filter_init(&can_filter);
  231. /* CAN1 filter number */
  232. #if 1
  233. can_filter.filter_number = 1;
  234. can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16);
  235. can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0);
  236. can_filter_init(&can_filter);
  237. can_filter.filter_number = 2;
  238. can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16);
  239. can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0);
  240. can_filter_init(&can_filter);
  241. #endif
  242. Can_NVIC_Config();
  243. can_interrupt_enable(CAN0, CAN_INT_RFNE0);
  244. }
  245. /**
  246. * @brief Configures the CAN.
  247. * @param None
  248. * @retval None
  249. */
  250. void CAN_Config(void)
  251. {
  252. memcpy(&can_ctr_self.head,&filter_ctr_self_id,sizeof(filter_ctr_self_id));
  253. memcpy(&can_ctr_bro.head,&filter_ctr_bro_id,sizeof(filter_ctr_bro_id));
  254. memcpy(&can_test_bro.head,&filter_test_bro_id,sizeof(filter_test_bro_id));
  255. can_ctr_self.data = can_rx_ctr_self_buf;
  256. can_ctr_bro.data = can_rx_ctr_bro_buf;
  257. can_test_bro.data = can_rx_test_bro_buf;
  258. /* enable CAN clock */
  259. rcu_periph_clock_enable(RCU_CAN0);
  260. rcu_periph_clock_enable(RCU_GPIOB);
  261. rcu_periph_clock_enable(RCU_AF);
  262. /* configure CAN0 GPIO */
  263. gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
  264. gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
  265. gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
  266. rcu_periph_clock_enable(RCU_GPIOA);
  267. gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
  268. //Silent_Enable(1);
  269. Silent_Enable(0);
  270. can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
  271. can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
  272. /* initialize CAN register */
  273. can_deinit(CAN0);
  274. /* initialize CAN parameters */
  275. can_parameter.time_triggered = DISABLE;
  276. can_parameter.auto_bus_off_recovery = DISABLE;
  277. can_parameter.auto_wake_up = DISABLE;
  278. can_parameter.auto_retrans = DISABLE;
  279. can_parameter.rec_fifo_overwrite = DISABLE;
  280. can_parameter.trans_fifo_order = ENABLE;
  281. can_parameter.working_mode = CAN_NORMAL_MODE;
  282. can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
  283. can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
  284. can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
  285. /* 1MBps */
  286. #if CAN_BAUDRATE == 1000
  287. can_parameter.prescaler = 6;
  288. /* 500KBps */
  289. #elif CAN_BAUDRATE == 500
  290. can_parameter.prescaler = 12;
  291. /* 250KBps */
  292. #elif CAN_BAUDRATE == 250
  293. can_parameter.prescaler = 24;
  294. /* 125KBps */
  295. #elif CAN_BAUDRATE == 125
  296. can_parameter.prescaler = 48;
  297. /* 100KBps */
  298. #elif CAN_BAUDRATE == 100
  299. can_parameter.prescaler = 60;
  300. /* 50KBps */
  301. #elif CAN_BAUDRATE == 50
  302. can_parameter.prescaler = 120;
  303. /* 20KBps */
  304. #elif CAN_BAUDRATE == 20
  305. can_parameter.prescaler = 300;
  306. #else
  307. #error "please select list can baudrate in private defines in drv_can.c "
  308. #endif
  309. /* initialize CAN */
  310. can_init(CAN0, &can_parameter);
  311. /* initialize filter */
  312. can_filter.filter_number=0;
  313. can_filter.filter_mode = CAN_FILTERMODE_MASK;
  314. can_filter.filter_bits = CAN_FILTERBITS_32BIT;
  315. #if 1
  316. can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16);
  317. can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0);
  318. can_filter.filter_mask_high = 0x0001;
  319. can_filter.filter_mask_low = 0xFFFF;
  320. #else
  321. can_filter.filter_list_high = 0x0000;
  322. can_filter.filter_list_low = 0x0000;
  323. can_filter.filter_mask_high = 0x0000;
  324. can_filter.filter_mask_low = 0x0000;
  325. #endif
  326. can_filter.filter_fifo_number = CAN_FIFO0;
  327. can_filter.filter_enable = ENABLE;
  328. can_filter_init(&can_filter);
  329. /* CAN1 filter number */
  330. #if 1
  331. can_filter.filter_number = 1;
  332. can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16);
  333. can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0);
  334. can_filter_init(&can_filter);
  335. can_filter.filter_number = 2;
  336. can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16);
  337. can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0);
  338. can_filter_init(&can_filter);
  339. #endif
  340. Can_NVIC_Config();
  341. can_interrupt_enable(CAN0, CAN_INT_RFNE0);
  342. }
  343. void USBD_LP_CAN0_RX0_IRQHandler(void)
  344. {
  345. can_receive_message_struct Rxmessage;
  346. CAN_FRAME* cf_temp;
  347. uint32_t head,buf_max;
  348. can_message_receive(CAN0, CAN_FIFO0, &Rxmessage);
  349. switch(Rxmessage.rx_fi)
  350. {
  351. case 0:
  352. cf_temp = &can_ctr_self;
  353. buf_max = sizeof(can_rx_ctr_self_buf);
  354. break;
  355. case 1:
  356. cf_temp = &can_ctr_bro;
  357. buf_max = sizeof(can_rx_ctr_bro_buf);
  358. break;
  359. case 2:
  360. cf_temp = &can_test_bro;
  361. buf_max = sizeof(can_rx_test_bro_buf);
  362. break;
  363. default:return;
  364. }
  365. head = (Rxmessage.rx_efid << 3)|(Rxmessage.rx_ff)|(Rxmessage.rx_ft);
  366. memcpy(&cf_temp->head,&head,sizeof(head));
  367. if(get_index_total_value(cf_temp->head.index) > get_index_total_value(cf_temp->head.total))
  368. return;
  369. head = get_index_total_value(cf_temp->head.total)*8UL;
  370. if(head > buf_max)
  371. return;
  372. head = get_index_total_value(cf_temp->head.index) - 1;
  373. memcpy(&cf_temp->data[head<<3],Rxmessage.rx_data,Rxmessage.rx_dlen);
  374. if(get_index_total_value(cf_temp->head.index) == get_index_total_value(cf_temp->head.total))
  375. {
  376. cf_temp->len = (head << 3) + Rxmessage.rx_dlen;
  377. //g_event |= EVENT_CAN_RECEIVE_FINISH;
  378. }
  379. }
  380. static u8 shark_can_log_buff[8];
  381. static u8 shark_can_log_length;
  382. //
  383. //ÓÃÓÚϵͳµ÷ÓÃprintf
  384. //
  385. int fputc(int ch, FILE *f)
  386. {
  387. if (ch == '\n') {
  388. if (shark_can_log_length > 0) {
  389. shark_can_send(0x72, 0x42, 3, shark_can_log_buff, shark_can_log_length);
  390. shark_can_log_length = 0;
  391. }
  392. } else if (shark_can_log_length < sizeof(shark_can_log_buff)) {
  393. shark_can_log_buff[shark_can_log_length] = ch;
  394. shark_can_log_length++;
  395. } else {
  396. shark_can_send(0x70, 0x42, 3, shark_can_log_buff, shark_can_log_length);
  397. shark_can_log_buff[0] = ch;
  398. shark_can_log_length = 1;
  399. }
  400. return ch;
  401. }
  402. //********************************************************CAN-END**********************************************************