Files
checker_slave/source/interface/if_can.c

427 lines
10 KiB
C
Raw Normal View History

2023-10-31 23:52:32 +08:00
#include "stm32f10x.h"
#include "if_can.h"
#include "rtthread.h"
#include "rthw.h"
#include "elec_det.h"
#include "board.h"
#include "core_delay.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;
if(elec_hard_version()==1){
CAN_InitStructure.CAN_Prescaler = 60;
}else{
CAN_InitStructure.CAN_Prescaler = 30;
}
CAN_Init(CAN1, &CAN_InitStructure);
Can_Device_ID = elec_local_addr();
yeid_un.Exide = 0;
yeid_un.yecanid_old.ACK = 0;
yeid_un.yecanid_old.FunClass = 0;
yeid_un.yecanid_old.Reserve1 = 0;
yeid_un.yecanid_old.Reserve0 = 0;
yeid_un.yecanid_old.SegFlag = 0;
yeid_un.yecanid_old.SegNum = 0;
yeid_un.yecanid_old.srcMACID = 0x00;
yeid_un.yecanid_old.destMACID = 0x1F;
ul_mask = GetCanFilter(yeid_un);
ul_can_mask =ul_mask;
yeid_un.yecanid_old.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_old.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_old.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,int delay_ms)
{
CanTxMsg transmit_message;
uint8_t mailbox_number;
YeCanID_un yeid_un;
uint32_t time_out = delay_ms*1000;
uint8_t uc_rtv = 0;
uint32_t tick_start=0;
uint8_t pack_len;
tick_start=delay_get_us();
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;
yeid_un.yecanid.Reserve0=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);
}else{
while(len > 0)
{
pack_len=8;
if(len<pack_len){
pack_len=len;
}
memcpy(transmit_message.Data,txdata,pack_len);
if(yeid_un.yecanid.SegNum == 0){
yeid_un.yecanid.SegFlag = 0x01;
}else if(len>8){
yeid_un.yecanid.SegFlag = 0x02;
}else{
yeid_un.yecanid.SegFlag = 0x03;
}
len -= pack_len;
txdata += pack_len;
transmit_message.DLC = pack_len;
transmit_message.ExtId = yeid_un.Exide;
while(mailbox_number = CAN_Transmit(CAN1, &transmit_message),mailbox_number==CAN_TxStatus_NoMailBox)
//while( CAN_TxStatus_Ok != CAN_TransmitStatus(CAN1,mailbox_number))
{
rt_hw_us_delay(20);
if(delay_check(tick_start,time_out))
{
uc_rtv = 1;
goto can0_tx_end;
}
}
yeid_un.yecanid.SegNum ++;
}
}
can0_tx_end:
CAN0_TX_BUSY_Flag = 0;
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;
uint8_t seg,seg_num,dstaddr;
yeid_un.Exide = receive_message.ExtId;
ul_exid = yeid_un.Exide << 3;
ul_exid &= ul_can_mask;
if(yeid_un.yecanid.Reserve0==0){
seg=yeid_un.yecanid_old.SegFlag;
seg_num=yeid_un.yecanid_old.SegNum;
dstaddr=yeid_un.yecanid_old.destMACID;
}else{
seg=yeid_un.yecanid.SegFlag;
seg_num=yeid_un.yecanid.SegNum;
dstaddr=yeid_un.yecanid.destMACID;
}
if((dstaddr!=elec_local_addr())&&(dstaddr!=0x1f)){
return;
}
if(receive_message.DLC > 0)
{
if(seg == 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(seg == 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(seg == 0x02)
{
if((canrx_st.seg_num+1) == seg_num )
{
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(seg == 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,int timeout_ms)
{
uint8_t src=elec_local_addr();
uint8_t dst=0;
uint8_t ret;
ret=YeCan_SendFrame(src,dst,b,len,timeout_ms);
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类型0uart1can
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,int timeout_ms)
{
h_self_def *h=&g_hself;
uart_def *s=h->dev[h->dev_index];
return s->write(s,b,len,timeout_ms);
}
uart_init_export(host,h_init,h_deinit,h_set_irq,h_set_end_irq,h_read,h_write,0)