#include "stm32f10x.h" #include "if_can.h" #include "rtthread.h" #include "rthw.h" #include "elec_det.h" #include "board.h" CanRxMsg receive_message; static YeCanRxFrame_st canrx_st; static uint8_t Can_Device_ID = 0; static uint32_t GetCanFilter(YeCanID_un yeid); uint32_t ul_exid,ul_can_mask; rt_mutex_t can_tx_mutex; volatile uint8_t CAN0_TX_BUSY_Flag = 0; /* @brief CAN通讯初始化, 包括CANgpio 过滤器 */ void YeCanInit(void) { uint32_t ul_filter,ul_mask; CAN_InitTypeDef CAN_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; YeCanID_un yeid_un; CAN_FilterInitTypeDef CAN_FilterInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //CAN GPIO 初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = ENABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; CAN_InitStructure.CAN_Prescaler = 30; CAN_Init(CAN1, &CAN_InitStructure); Can_Device_ID = elec_local_addr(); yeid_un.Exide = 0; yeid_un.yecanid.ACK = 0; yeid_un.yecanid.FunClass = 0; yeid_un.yecanid.Reserve1 = 0; yeid_un.yecanid.Reserve0 = 0; yeid_un.yecanid.SegFlag = 0; yeid_un.yecanid.SegNum = 0; yeid_un.yecanid.srcMACID = 0x00; yeid_un.yecanid.destMACID = 0x1F; ul_mask = GetCanFilter(yeid_un); ul_can_mask =ul_mask; yeid_un.yecanid.destMACID = Can_Device_ID; ul_filter = GetCanFilter(yeid_un); CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = (ul_filter >> 16) & 0x0FFFF;; CAN_FilterInitStructure.CAN_FilterIdLow = ul_filter & 0x0FFFF;; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (ul_mask >> 16) & 0x0FFFF;; CAN_FilterInitStructure.CAN_FilterMaskIdLow = ul_mask & 0x0FFFF; ; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); yeid_un.yecanid.destMACID = 0x1E; ul_filter = GetCanFilter(yeid_un); CAN_FilterInitStructure.CAN_FilterNumber = 1; CAN_FilterInitStructure.CAN_FilterIdHigh = (ul_filter >> 16) & 0x0FFFF;; CAN_FilterInitStructure.CAN_FilterIdLow = ul_filter & 0x0FFFF;; CAN_FilterInit(&CAN_FilterInitStructure); yeid_un.yecanid.destMACID = 0x1F; ul_filter = GetCanFilter(yeid_un); CAN_FilterInitStructure.CAN_FilterNumber = 2; CAN_FilterInitStructure.CAN_FilterIdHigh = (ul_filter >> 16) & 0x0FFFF;; CAN_FilterInitStructure.CAN_FilterIdLow = ul_filter & 0x0FFFF;; CAN_FilterInit(&CAN_FilterInitStructure); CAN_OperatingModeRequest(CAN1,CAN_OperatingMode_Normal); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0); CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); can_tx_mutex = rt_mutex_create ("can0_tx_mutex",RT_IPC_FLAG_PRIO); } /* @brief 根据设置CAN 的ID协议,获取帧过滤值 */ static uint32_t GetCanFilter(YeCanID_un yeid) { uint32_t filter = 0; filter = yeid.Exide << 3; filter |= 0x04;//只接收扩展帧 filter &= ~((uint32_t)0x003);//不限定帧类型 return filter; } /* @brief CAN发送通讯帧 @param 源地址 @param 主机地址 @param 发送数据缓存 @param 发送数据长度 @rtv 0 成功 1 失败 */ uint8_t YeCan_SendFrame(uint8_t srcaddr,uint8_t dstaddr,const uint8_t* txdata, uint16_t len) { CanTxMsg transmit_message; uint8_t mailbox_number; YeCanID_un yeid_un; uint32_t time_out = 0; uint8_t uc_rtv = 0; //can_transmission_stop(CAN1,0); /* initialize transmit message */ transmit_message.ExtId = 0x00; transmit_message.StdId = 0x00; transmit_message.RTR = CAN_RTR_DATA; transmit_message.IDE = CAN_ID_EXT; yeid_un.Exide = 0; yeid_un.yecanid.srcMACID = srcaddr; yeid_un.yecanid.destMACID = dstaddr; yeid_un.yecanid.ACK = 0; yeid_un.yecanid.FunClass = 1; yeid_un.yecanid.SegFlag = 0; yeid_un.yecanid.SegNum = 0; if(srcaddr == 0x00 || srcaddr == 0x1f) { time_out = 0; while(time_out < 5) { elec_led1_power(0); rt_thread_mdelay(50); elec_led1_power(1); rt_thread_mdelay(50); time_out++; } } if(can_tx_mutex != RT_NULL) { if(RT_EOK != rt_mutex_take (can_tx_mutex,500)) { return 1; } } if(len <= 8) { transmit_message.DLC = len; transmit_message.ExtId = yeid_un.Exide; memcpy(transmit_message.Data,txdata,8); mailbox_number = CAN_Transmit(CAN1, &transmit_message); time_out = 5000; while( CAN_TxStatus_Ok != CAN_TransmitStatus(CAN1,mailbox_number) && time_out > 0) { time_out --; rt_hw_us_delay(20); } if(time_out == 0) { uc_rtv = 1; goto can0_tx_end; } goto can0_tx_end; } while(len > 8) { memcpy(transmit_message.Data,txdata,8); len -= 8; txdata += 8; if(yeid_un.yecanid.SegNum == 0) { yeid_un.yecanid.SegFlag = 0x01; }else { yeid_un.yecanid.SegFlag = 0x02; } transmit_message.ExtId = yeid_un.Exide; transmit_message.DLC = 8; mailbox_number = CAN_Transmit(CAN1, &transmit_message); time_out = 5000; while( CAN_TxStatus_Ok != CAN_TransmitStatus(CAN1,mailbox_number) && time_out > 0) { time_out --; rt_hw_us_delay(20); } if(time_out == 0) { uc_rtv = 1; goto can0_tx_end; } yeid_un.yecanid.SegNum ++; } yeid_un.yecanid.SegFlag = 0x3; memcpy(transmit_message.Data,txdata,len); transmit_message.DLC = len; transmit_message.ExtId = yeid_un.Exide; mailbox_number = CAN_Transmit(CAN1, &transmit_message); time_out = 5000; while(CAN_TxStatus_Ok != CAN_TransmitStatus(CAN1,mailbox_number) && time_out > 0) { time_out --; rt_hw_us_delay(20); } if(time_out == 0) { uc_rtv = 1; } can0_tx_end: CAN0_TX_BUSY_Flag = 0; rt_mutex_release(can_tx_mutex); return uc_rtv; } typedef struct{ void (*end_irq)(void *t,uint32_t len); void *t; uint32_t rx_buff_size; }self_def; static self_def g_self; static void save_data(void) { YeCanID_un yeid_un; if(receive_message.DLC > 0) { yeid_un.Exide = receive_message.ExtId; ul_exid = yeid_un.Exide << 3; ul_exid &= ul_can_mask; if(yeid_un.yecanid.SegFlag == 00) { memcpy(canrx_st.rx_databuf,receive_message.Data,receive_message.DLC); canrx_st.rx_index = receive_message.DLC; g_self.end_irq(g_self.t,canrx_st.rx_index); } else if(yeid_un.yecanid.SegFlag == 0x01) { canrx_st.seg_num = 0; memcpy(canrx_st.rx_databuf,receive_message.Data,receive_message.DLC); canrx_st.rx_index = receive_message.DLC; }else if(yeid_un.yecanid.SegFlag == 0x02) { if((canrx_st.seg_num+1) == yeid_un.yecanid.SegNum ) { canrx_st.seg_num++; memcpy(canrx_st.rx_databuf+canrx_st.rx_index,receive_message.Data,receive_message.DLC); canrx_st.rx_index += receive_message.DLC; }else{ //error } }else if(yeid_un.yecanid.SegFlag == 0x03) { memcpy(canrx_st.rx_databuf+canrx_st.rx_index,receive_message.Data,receive_message.DLC); canrx_st.rx_index += receive_message.DLC; g_self.end_irq(g_self.t,canrx_st.rx_index); } } } void USB_LP_CAN1_RX0_IRQHandler(void) { rt_interrupt_enter(); CAN_Receive(CAN1, CAN_FIFO0, &receive_message); if(g_self.end_irq&&canrx_st.rx_databuf){ save_data(); } CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0); rt_interrupt_leave(); } static int init(uart_def *u,int bsp) { YeCanInit(); return 0; } static int deinit(uart_def *u) { return 0; } static int set_irq(uart_def *u,void (*irq)(void *t,uint8_t d),void *t) { return 0; } static int set_end_irq(uart_def *u,uint8_t *rx_buff,int rx_buff_size, void (*irq)(void *t,uint32_t len),void *t) { irq_disable(); g_self.end_irq=irq; canrx_st.rx_databuf=rx_buff; g_self.rx_buff_size=rx_buff_size; g_self.t=t; irq_enable(); return 0; } static int read(uart_def *u,uint8_t *b,int len) { return 0; } static int write(uart_def *u,const uint8_t *b,int len) { uint8_t src=b[4]; uint8_t dst=b[5]; uint8_t ret; ret=YeCan_SendFrame(src,dst,b,len); if(ret==0) return len; else return 0; } uart_init_export(can,init,deinit,set_irq,set_end_irq,read,write,0) typedef struct{ uart_def *dev[2]; int dev_index; int inited; void (*end_irq)(void *t,uint32_t len); void *t; }h_self_def; static h_self_def g_hself; static int h_init(uart_def *u,int bsp) { h_self_def *h=&g_hself; if(h->inited) return 0; // 设置主机接口 int类型,0uart,1can app_variable("host_if",&h->dev_index,0); h->dev[0]=dev_get("uart1"); h->dev[1]=dev_get("can"); h->dev[0]->init(h->dev[0],0); h->dev[1]->init(h->dev[1],0); return 0; } static int h_deinit(uart_def *u) { return 0; } static int h_set_irq(uart_def *u,void (*irq)(void *t,uint8_t d),void *t) { return 0; } static void h_end_irq0(void *t,uint32_t len) { h_self_def *h=&g_hself; h->dev_index=0; if(h->end_irq) { h->end_irq(h->t,len); } } static void h_end_irq1(void *t,uint32_t len) { h_self_def *h=&g_hself; h->dev_index=1; if(h->end_irq) { h->end_irq(h->t,len); } } static int h_set_end_irq(uart_def *u,uint8_t *rx_buff,int rx_buff_size, void (*irq)(void *t,uint32_t len),void *t) { h_self_def *h=&g_hself; irq_disable(); h->end_irq=irq; h->t=t; irq_enable(); h->dev[0]->set_end_irq(h->dev[0],rx_buff,rx_buff_size,h_end_irq0,h); h->dev[1]->set_end_irq(h->dev[1],rx_buff,rx_buff_size,h_end_irq1,h); return 0; } static int h_read(uart_def *u,uint8_t *b,int len) { return 0; } static int h_write(uart_def *u,const uint8_t *b,int len) { h_self_def *h=&g_hself; uart_def *s=h->dev[h->dev_index]; return s->write(s,b,len); } uart_init_export(host,h_init,h_deinit,h_set_irq,h_set_end_irq,h_read,h_write,0)