#include "common.h" #include "drv_can.h" #include "drv_io.h" extern uint8_t work_normal; //********************************************************CAN-START********************************************************** static uint8_t can_tx_buf[CAN_TX_BUF_MAX]; static uint8_t can_rx_ctr_self_buf[CAN_RX_BUF_MAX]; static uint8_t can_rx_ctr_bro_buf[CAN_RX_CTR_BRO_BUF_MAX]; static uint8_t can_rx_test_bro_buf[CAN_RX_TEST_BRO_BUF_MAX]; can_parameter_struct can_parameter; can_filter_parameter_struct can_filter; #define CAN_BAUDRATE 250 uint32_t filter_ctr_self_id = (CTR_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA; uint32_t filter_ctr_bro_id = (CTR_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA; #ifdef CONFIG_CAN_IAP uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA; #else uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA; #endif CAN_FRAME can_ctr_self; CAN_FRAME can_ctr_bro; CAN_FRAME can_test_bro; static CAN_FRAME can_tx_frame; static uint8_t can_busy = 0; void Can_Stop_Send(void) { can_busy = 0; } void Check_Can_Poll(void) { if(work_normal) { if(can_error_get(CAN0) != CAN_ERROR_NONE) { Can_Power_Enable(0); can_deinit(CAN0); CAN_Config_HW(); Can_Power_Enable(1); can_busy = 0; } } } static void Reset_Can_Rx_Buffer(CAN_FRAME*can_frame) { if(can_frame == NULL) return; memset(&can_frame->head,0x00,sizeof(can_frame->head)); can_frame->len = 0; } uint16_t Get_Data_Can(CAN_FRAME*app_can_frame) { CAN_FRAME* cf_temp = NULL; if(app_can_frame == NULL) return 0; 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) cf_temp = &can_ctr_self; 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) cf_temp = &can_ctr_bro; 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) cf_temp = &can_test_bro; if(cf_temp == NULL) return 0; memcpy(&app_can_frame->head,&cf_temp->head,sizeof(cf_temp->head)); memcpy(app_can_frame->data,cf_temp->data,cf_temp->len); app_can_frame->len = cf_temp->len; Reset_Can_Rx_Buffer(cf_temp); return app_can_frame->len; } int8_t Send_Data_Can(CAN_FRAME*app_can_frame,uint8_t from) { can_trasnmit_message_struct can_tr_m; uint32_t exid = 0; if(app_can_frame == NULL || can_busy || work_normal == 0) return 0; //Silent_Enable(0); //delay_1us(100); memcpy(&can_tx_frame.head,&app_can_frame->head,sizeof(can_tx_frame.head)); can_tx_frame.len = app_can_frame->len; memcpy(can_tx_frame.data,app_can_frame->data,can_tx_frame.len); memset(&can_tr_m,0x00,sizeof(can_tr_m)); memcpy(&exid,&can_tx_frame.head,sizeof(exid)); can_tr_m.tx_efid = (exid>>3); can_tr_m.tx_ff = CAN_FF_EXTENDED; can_tr_m.tx_ft = CAN_FT_DATA; if(can_tx_frame.len > 8) can_tr_m.tx_dlen = 8; else can_tr_m.tx_dlen = can_tx_frame.len; memcpy(can_tr_m.tx_data,can_tx_frame.data,can_tr_m.tx_dlen); if(can_message_transmit(CAN0,&can_tr_m) == CAN_NOMAILBOX) return 0; if(can_tx_frame.head.total != 1) { can_busy = 1; can_interrupt_enable(CAN0, CAN_INT_TME); } return 1; } static void Can_NVIC_Config(void) { nvic_irq_enable(USBD_HP_CAN0_TX_IRQn,3,0); nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn,3,0); } /** * @brief Configures the CAN. * @param None * @retval None */ void CAN_Config_HW(void) { /* enable CAN clock */ rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_AF); /* configure CAN0 GPIO */ gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8); gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9); gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE); rcu_periph_clock_enable(RCU_GPIOA); gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7); Silent_Enable(0); can_struct_para_init(CAN_INIT_STRUCT, &can_parameter); can_struct_para_init(CAN_INIT_STRUCT, &can_filter); /* initialize CAN register */ can_deinit(CAN0); /* initialize CAN parameters */ can_parameter.time_triggered = DISABLE; can_parameter.auto_bus_off_recovery = DISABLE; can_parameter.auto_wake_up = DISABLE; can_parameter.auto_retrans = DISABLE; can_parameter.rec_fifo_overwrite = DISABLE; can_parameter.trans_fifo_order = DISABLE; can_parameter.working_mode = CAN_NORMAL_MODE; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.time_segment_1 = CAN_BT_BS1_5TQ; can_parameter.time_segment_2 = CAN_BT_BS2_3TQ; /* 1MBps */ #if CAN_BAUDRATE == 1000 can_parameter.prescaler = 6; /* 500KBps */ #elif CAN_BAUDRATE == 500 can_parameter.prescaler = 12; /* 250KBps */ #elif CAN_BAUDRATE == 250 can_parameter.prescaler = 24; /* 125KBps */ #elif CAN_BAUDRATE == 125 can_parameter.prescaler = 48; /* 100KBps */ #elif CAN_BAUDRATE == 100 can_parameter.prescaler = 60; /* 50KBps */ #elif CAN_BAUDRATE == 50 can_parameter.prescaler = 120; /* 20KBps */ #elif CAN_BAUDRATE == 20 can_parameter.prescaler = 300; #else #error "please select list can baudrate in private defines in drv_can.c " #endif /* initialize CAN */ can_init(CAN0, &can_parameter); /* initialize filter */ can_filter.filter_number=0; can_filter.filter_mode = CAN_FILTERMODE_MASK; can_filter.filter_bits = CAN_FILTERBITS_32BIT; #if 1 can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0); can_filter.filter_mask_high = 0x0001; can_filter.filter_mask_low = 0xFFFF; #else can_filter.filter_list_high = 0x0000; can_filter.filter_list_low = 0x0000; can_filter.filter_mask_high = 0x0000; can_filter.filter_mask_low = 0x0000; #endif can_filter.filter_fifo_number = CAN_FIFO0; can_filter.filter_enable = ENABLE; can_filter_init(&can_filter); /* CAN1 filter number */ #if 1 can_filter.filter_number = 1; can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0); can_filter_init(&can_filter); can_filter.filter_number = 2; can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0); can_filter_init(&can_filter); #endif Can_NVIC_Config(); can_interrupt_enable(CAN0, CAN_INT_RFNE0); } /** * @brief Configures the CAN. * @param None * @retval None */ void CAN_Config(void) { memcpy(&can_ctr_self.head,&filter_ctr_self_id,sizeof(filter_ctr_self_id)); memcpy(&can_ctr_bro.head,&filter_ctr_bro_id,sizeof(filter_ctr_bro_id)); memcpy(&can_test_bro.head,&filter_test_bro_id,sizeof(filter_test_bro_id)); can_ctr_self.data = can_rx_ctr_self_buf; can_ctr_bro.data = can_rx_ctr_bro_buf; can_test_bro.data = can_rx_test_bro_buf; memset(&can_tx_frame,0x00,sizeof(can_tx_frame)); memset(can_tx_buf,0x00,sizeof(can_tx_buf)); can_tx_frame.data = can_tx_buf; /* enable CAN clock */ rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_AF); /* configure CAN0 GPIO */ gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8); gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9); gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE); rcu_periph_clock_enable(RCU_GPIOA); gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7); //Silent_Enable(1); Silent_Enable(0); can_struct_para_init(CAN_INIT_STRUCT, &can_parameter); can_struct_para_init(CAN_INIT_STRUCT, &can_filter); /* initialize CAN register */ can_deinit(CAN0); /* initialize CAN parameters */ can_parameter.time_triggered = DISABLE; can_parameter.auto_bus_off_recovery = DISABLE; can_parameter.auto_wake_up = DISABLE; can_parameter.auto_retrans = DISABLE; can_parameter.rec_fifo_overwrite = DISABLE; can_parameter.trans_fifo_order = DISABLE; can_parameter.working_mode = CAN_NORMAL_MODE; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.time_segment_1 = CAN_BT_BS1_5TQ; can_parameter.time_segment_2 = CAN_BT_BS2_3TQ; /* 1MBps */ #if CAN_BAUDRATE == 1000 can_parameter.prescaler = 6; /* 500KBps */ #elif CAN_BAUDRATE == 500 can_parameter.prescaler = 12; /* 250KBps */ #elif CAN_BAUDRATE == 250 can_parameter.prescaler = 24; /* 125KBps */ #elif CAN_BAUDRATE == 125 can_parameter.prescaler = 48; /* 100KBps */ #elif CAN_BAUDRATE == 100 can_parameter.prescaler = 60; /* 50KBps */ #elif CAN_BAUDRATE == 50 can_parameter.prescaler = 120; /* 20KBps */ #elif CAN_BAUDRATE == 20 can_parameter.prescaler = 300; #else #error "please select list can baudrate in private defines in drv_can.c " #endif /* initialize CAN */ can_init(CAN0, &can_parameter); /* initialize filter */ can_filter.filter_number=0; can_filter.filter_mode = CAN_FILTERMODE_MASK; can_filter.filter_bits = CAN_FILTERBITS_32BIT; #if 1 can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0); can_filter.filter_mask_high = 0x0001; can_filter.filter_mask_low = 0xFFFF; #else can_filter.filter_list_high = 0x0000; can_filter.filter_list_low = 0x0000; can_filter.filter_mask_high = 0x0000; can_filter.filter_mask_low = 0x0000; #endif can_filter.filter_fifo_number = CAN_FIFO0; can_filter.filter_enable = ENABLE; can_filter_init(&can_filter); /* CAN1 filter number */ #if 1 can_filter.filter_number = 1; can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0); can_filter_init(&can_filter); can_filter.filter_number = 2; can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16); can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0); can_filter_init(&can_filter); #endif Can_NVIC_Config(); can_interrupt_enable(CAN0, CAN_INT_RFNE0); } void USBD_HP_CAN0_TX_IRQHandler(void) { can_trasnmit_message_struct can_tr_m; uint32_t exid = 0; if(can_tx_frame.head.index != can_tx_frame.head.total) { can_tx_frame.head.index++; memset(&can_tr_m,0x00,sizeof(can_tr_m)); memcpy(&exid,&can_tx_frame.head,sizeof(exid)); can_tr_m.tx_efid = (exid>>3); can_tr_m.tx_ff = CAN_FF_EXTENDED; can_tr_m.tx_ft = CAN_FT_DATA; exid = get_index_total_value(can_tx_frame.head.index) -1; exid <<= 3; if(can_tx_frame.head.index != can_tx_frame.head.total) can_tr_m.tx_dlen = 8; else can_tr_m.tx_dlen = can_tx_frame.len - exid; memcpy(can_tr_m.tx_data,&can_tx_frame.data[exid],can_tr_m.tx_dlen); can_message_transmit(CAN0,&can_tr_m); } else { can_busy = 0; can_interrupt_disable(CAN0, CAN_INT_TME); //Silent_Enable(1); } } void USBD_LP_CAN0_RX0_IRQHandler(void) { can_receive_message_struct Rxmessage; CAN_FRAME* cf_temp; uint32_t head,buf_max; can_message_receive(CAN0, CAN_FIFO0, &Rxmessage); switch(Rxmessage.rx_fi) { case 0: cf_temp = &can_ctr_self; buf_max = sizeof(can_rx_ctr_self_buf); break; case 1: cf_temp = &can_ctr_bro; buf_max = sizeof(can_rx_ctr_bro_buf); break; case 2: cf_temp = &can_test_bro; buf_max = sizeof(can_rx_test_bro_buf); break; default:return; } head = (Rxmessage.rx_efid << 3)|(Rxmessage.rx_ff)|(Rxmessage.rx_ft); memcpy(&cf_temp->head,&head,sizeof(head)); if(get_index_total_value(cf_temp->head.index) > get_index_total_value(cf_temp->head.total)) return; head = get_index_total_value(cf_temp->head.total)*8UL; if(head > buf_max) return; head = get_index_total_value(cf_temp->head.index) - 1; memcpy(&cf_temp->data[head<<3],Rxmessage.rx_data,Rxmessage.rx_dlen); if(get_index_total_value(cf_temp->head.index) == get_index_total_value(cf_temp->head.total)) { cf_temp->len = (head << 3) + Rxmessage.rx_dlen; //g_event |= EVENT_CAN_RECEIVE_FINISH; } } #if 1 // //用于系统调用printf // #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ PUTCHAR_PROTOTYPE { if(work_normal) { can_trasnmit_message_struct can_tr_m; memset(&can_tr_m,0x00,sizeof(can_tr_m)); can_tr_m.tx_efid = (SELF_ID << 7)|(PRINTF_TER_ID << 0); can_tr_m.tx_ff = CAN_FF_EXTENDED; can_tr_m.tx_ft = CAN_FT_DATA; can_tr_m.tx_dlen = 1; can_tr_m.tx_data[0] = (uint8_t)ch; can_message_transmit(CAN0,&can_tr_m); delay_1us(500); } return ch; } #endif //********************************************************CAN-END**********************************************************