can.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <stdio.h>
  2. #include "bsp.h"
  3. #include "can.h"
  4. #define CAN_RX_MESSAGE_RX_ID 1
  5. #define CAN_SEND_QUEUE_SIZE 32
  6. #define RX_ID_OFFSET 16
  7. #define CAN_SEND_OK 0
  8. #define CAN_SEND_ERROR -1
  9. #define CAN_SEND_WAIT_TIMEOUT -2
  10. static can_receive_message_struct can_message;
  11. static int shark_send_can0_to_fifo(can_trasnmit_message_struct *P_message);
  12. static int shark_send_can0_data(can_trasnmit_message_struct *P_message);
  13. /* this function can be overide by app, which need recv the can frame */
  14. __weak void put_raw_message(can_id_t id, uint8_t *data, int len){
  15. }
  16. static __inline__ void can_fifo_recv(int fifo){
  17. can_receive_message_struct *message = &can_message;
  18. can_message_receive(CAN0, fifo, message);
  19. put_raw_message((can_id_t)message->rx_efid, message->rx_data, message->rx_dlen);
  20. }
  21. void USBD_LP_CAN0_RX0_IRQHandler(void)
  22. {
  23. can_fifo_recv(CAN_FIFO0);
  24. }
  25. void CAN0_RX1_IRQHandler(void)
  26. {
  27. can_fifo_recv(CAN_FIFO1);
  28. }
  29. static void shark_can0_txrx_pin_config(void){
  30. /* enable can clock */
  31. rcu_periph_clock_enable(RCU_CAN0);
  32. rcu_periph_clock_enable(RCU_GPIOB);
  33. rcu_periph_clock_enable(RCU_AF);
  34. gpio_pin_remap_config(GPIO_CAN_FULL_REMAP,DISABLE);
  35. gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
  36. gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  37. gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  38. }
  39. static void shark_can0_config(void)
  40. {
  41. can_parameter_struct can_parameter;
  42. can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
  43. /* initialize CAN register */
  44. can_deinit(CAN0);
  45. //can_deinit(CAN1);
  46. /* initialize CAN parameters */
  47. can_parameter.time_triggered = DISABLE;
  48. can_parameter.auto_bus_off_recovery = ENABLE;
  49. can_parameter.auto_wake_up = DISABLE;
  50. can_parameter.rec_fifo_overwrite = DISABLE;
  51. can_parameter.trans_fifo_order = ENABLE;
  52. can_parameter.no_auto_retrans = ENABLE;
  53. #if CAN0_SPEED==250 //250k bps
  54. if (SystemCoreClock == 120000000) {
  55. can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
  56. can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
  57. can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;
  58. } else {
  59. can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
  60. can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
  61. can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
  62. }
  63. #endif
  64. can_parameter.working_mode = CAN_NORMAL_MODE;
  65. can_parameter.prescaler = 24;
  66. /* initialize CAN */
  67. can_init(CAN0, &can_parameter);
  68. /* recv my can ID, use fifo0 */
  69. can_filter_mask_mode_init(CAN_MY_ADDRESS, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO0, 0);
  70. nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
  71. nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn,2,0);
  72. /* enable can receive FIFO0 not empty interrupt */
  73. can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
  74. /* recv broadcast, fifo1 */
  75. can_filter_mask_mode_init(CAN_NODE_ADDR_FF, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 1);
  76. /* recv ccu aux fifo2*/
  77. can_filter_mask_mode_init(CAN_NODE_ADDR_CCU_AUX, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 2);
  78. /* recv ble fifo3*/
  79. can_filter_mask_mode_init(CAN_NODE_ADDR_BLE, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 3);
  80. can_filter_mask_mode_init(CAN_NODE_ADDR_ACU, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 4);
  81. nvic_irq_enable(CAN0_RX1_IRQn,10,0);
  82. /* enable can receive FIFO1 not empty interrupt */
  83. can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE1);
  84. }
  85. static int shark_send_can0_data(can_trasnmit_message_struct *P_message){
  86. return shark_send_can0_to_fifo(P_message);
  87. }
  88. /*when system scheduler is not start or stoped, we MUST not use FreeRTOS
  89. system api which can cause sleep,context switch */
  90. static int shark_send_can0_to_fifo(can_trasnmit_message_struct *P_message){
  91. uint8_t mailbox_number = CAN_NOMAILBOX;
  92. uint32_t retry_count = 2000;
  93. if (CAN_ERR(CAN0) & CAN_ERR_BOERR){
  94. shark_can0_reset();
  95. }
  96. do {
  97. mailbox_number = can_message_transmit(CAN0, P_message);
  98. if (mailbox_number < CAN_NOMAILBOX){
  99. return CAN_SEND_OK;
  100. }
  101. }while(retry_count-- > 0); //wait sender fifo empty
  102. shark_can0_reset();
  103. return CAN_SEND_ERROR;
  104. }
  105. int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
  106. can_trasnmit_message_struct trasnmit_msg;
  107. can_id_t can_frame_id;
  108. U32 total_frames = ((len + 7) >> 3);
  109. int send_len = len;
  110. U32 frame_id = 1;
  111. can_frame_id.id = can_id;
  112. can_frame_id.total = total_frames;
  113. while(send_len > 0){
  114. can_frame_id.idx = frame_id;
  115. trasnmit_msg.tx_sfid = 0;
  116. trasnmit_msg.tx_efid = can_frame_id.id;
  117. trasnmit_msg.tx_ft = CAN_FT_DATA;
  118. trasnmit_msg.tx_ff = CAN_FF_EXTENDED;
  119. trasnmit_msg.tx_dlen = min(CAN_DATA_SIZE,send_len);
  120. memcpy((char *)trasnmit_msg.tx_data, (char *)buff + (len - send_len), trasnmit_msg.tx_dlen);
  121. send_len -= trasnmit_msg.tx_dlen;
  122. frame_id ++;
  123. if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
  124. return CAN_SEND_ERROR;
  125. }
  126. }
  127. return CAN_SEND_OK;
  128. }
  129. void shark_can0_reset(void){
  130. shark_can0_txrx_pin_config();
  131. shark_can0_config();
  132. }
  133. void shark_can0_deinit(void){
  134. can_deinit(CAN0);
  135. rcu_periph_clock_disable(RCU_CAN0);
  136. gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_9);
  137. }
  138. void shark_can0_init(void){
  139. shark_can0_txrx_pin_config();
  140. shark_can0_config();
  141. }