can.c 5.1 KB

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