STM32F103 CAN 驱动

#define DEF_DEBUG_TRACE
#define DEF_DEBUG_MSG
#define DEF_DEBUG_PRINTF
#define DEF_DEBUG_WARNING
#define DEF_DEBUG_ERROR
#include "debug.h"

#include "uart.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_can.h"

#include "drv_uart.h"
#include "stm32f10x_can.h"
#include "stm32f10x_gpio.h"
#include "bsp.h"
#include "drv_sys_time.h"

#include "drv_can.h"
#include "can.h"
#include "sys_config.h"
#include "config_mcu_periph.h"
#include "dasi_str.h"
#include "ex_datalink_port_pack.h"



#ifdef  ENABLE_CAN

#define CAN_RX_TX_MAX_LENGTH 	8


typedef struct
{
    GPIO_TypeDef   *gpio_group;
    uint16_t 		tx_gpio_pin;
    uint16_t 		rx_gpio_pin;
    uint32_t 		ptc_std_identify;
    uint32_t        rec_ex_can_id;
} drv_can_t;

CanTxMsg TxMessage;
CanRxMsg RxMessage;

static drv_can_t drv_can_info =
{
    .gpio_group         = GPIOB,
    .rx_gpio_pin        = GPIO_Pin_8,
    .tx_gpio_pin        = GPIO_Pin_9,

    .ptc_std_identify   = 0x20,
    .rec_ex_can_id = 0x16326000,
};


void drv_can_init(void)
{
  GPIO_InitTypeDef          GPIO_InitStructure;
  CAN_InitTypeDef           CAN_InitStructure;
  CAN_FilterInitTypeDef     CAN_FilterInitStructure;
  NVIC_InitTypeDef          NVIC_InitStructure;

    CAN_DeInit(CAN1);

    /* GPIO clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
#if 0

    /* Configure CAN pin: RX */
    GPIO_InitStructure.GPIO_Pin = drv_can_info.rx_gpio_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(drv_can_info.gpio_group, &GPIO_InitStructure);

    /* Configure CAN pin: TX */
    GPIO_InitStructure.GPIO_Pin = drv_can_info.tx_gpio_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(drv_can_info.gpio_group, &GPIO_InitStructure);

#else
    /* Configure CAN pin: RX */
    GPIO_InitStructure.GPIO_Pin = drv_can_info.rx_gpio_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(drv_can_info.gpio_group, &GPIO_InitStructure);

    /* Configure CAN pin: TX */
    GPIO_InitStructure.GPIO_Pin = drv_can_info.tx_gpio_pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(drv_can_info.gpio_group, &GPIO_InitStructure);


    GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

    /* CANx Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /* CAN register init */
    CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  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 = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

  /* CAN Baudrate = 500kbps*/
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
  CAN_InitStructure.CAN_Prescaler = 8;
  CAN_Init(CAN1, &CAN_InitStructure);

    /* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)(drv_can_info.ptc_std_identify << 5);
    CAN_FilterInitStructure.CAN_FilterIdLow = 0;//(uint16_t)(drv_can_info.ptc_std_identify<<3)|CAN_ID_EXT;
     
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xfffc;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 1;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    /* OPEN Reception IT */
    NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    CAN_ITConfig(CAN1, CAN_IT_TME,  ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_EWG, ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_EPV, ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_BOF, ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_LEC, ENABLE);
    CAN_ITConfig(CAN1, CAN_IT_ERR, ENABLE);
    /* receive */
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);



    TxMessage.StdId = 0x21;//drv_can_info.ptc_std_identify;
    TxMessage.ExtId = 0x12762000; //发送帧ID   0x12762000,接受扩展帧ID 0x16326000
    TxMessage.RTR   = CAN_RTR_DATA;
    TxMessage.IDE   = CAN_ID_STD;//使用标准帧
#endif
}

void can_transmit_isr_callback(void)
{
    if(CAN_GetITStatus(CAN1,CAN_IT_TME) == SET)
    {
        if(queue_empty(&get_can_info()->tx_queue) == FALSE)
        {
            CAN_ClearITPendingBit(CAN1,CAN_IT_TME);

            uint16_t value_length = queue_length(&get_can_info()->tx_queue);

            if(value_length >= CAN_RX_TX_MAX_LENGTH)
                value_length = CAN_RX_TX_MAX_LENGTH;

            TxMessage.DLC = value_length;

            for(uint8_t idx = 0; idx < value_length; idx++)
                TxMessage.Data[idx] = read_byte_queue(&get_can_info()->tx_queue);


            CAN_Transmit(CAN1, &TxMessage);
        }
        else
        {
            get_can_info()->tx_running = FALSE;
            CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);
        }
    }
}




void drv_can_disable(void)
{
    NVIC_InitTypeDef          NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , DISABLE);//关闭引脚重定向

    NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);

    CAN_ITConfig(CAN1,  CAN_IT_FMP1, DISABLE);
    CAN_ITConfig(CAN1,  CAN_IT_TME,  DISABLE);
    CAN_ITConfig(CAN1, CAN_IT_EWG, DISABLE);
    CAN_ITConfig(CAN1, CAN_IT_EPV, DISABLE);
    CAN_ITConfig(CAN1, CAN_IT_BOF, DISABLE);
    CAN_ITConfig(CAN1, CAN_IT_LEC, DISABLE);
    CAN_ITConfig(CAN1, CAN_IT_ERR, DISABLE);
}


uint16_t drv_can_puts(const uint8_t *src, uint16_t len)
{
    uint16_t real_len;
    CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);
    
    real_len = write_block_queue(&get_can_info()->tx_queue, src, len);

    if((get_can_info()->tx_running == FALSE) && (real_len > 0))
    {
        get_can_info()->tx_running = TRUE;
        uint16_t value_length = queue_length(&get_can_info()->tx_queue);

        if(value_length >= CAN_RX_TX_MAX_LENGTH)
            value_length = CAN_RX_TX_MAX_LENGTH;

        TxMessage.DLC = value_length;

        for(uint8_t idx = 0; idx < value_length; idx++)
            TxMessage.Data[idx] = read_byte_queue(&get_can_info()->tx_queue);


        CAN_Transmit(CAN1, &TxMessage);
        //DEBUG_MSG("manual transmit length:%d\r\n", TxMessage.DLC);
    }
    
    CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);


    return real_len;
}

void CAN1_SCE_IRQHandler(void)
{
    //DEBUG_PRINTF("CAN1\r\n");
    get_can_info()->can_error = TRUE;
    clear_queue(&get_can_info()->tx_queue);//清除发送队列
    get_can_info()->tx_running = TRUE;//禁止调度

    if(CAN_GetITStatus(CAN1,CAN_IT_EWG))
    {
        CAN_ClearITPendingBit(CAN1,CAN_IT_EWG);
        //DEBUG_PRINTF("EWG\r\n");
    }

    if(CAN_GetITStatus(CAN1,CAN_IT_EPV))
    {
        CAN_ClearITPendingBit(CAN1,CAN_IT_EPV);
        //DEBUG_PRINTF("EPV\r\n");
    }

    if(CAN_GetITStatus(CAN1,CAN_IT_BOF))
    {
        CAN_ClearITPendingBit(CAN1,CAN_IT_BOF);
        //DEBUG_PRINTF("BOF\r\n");
    }

    if(CAN_GetITStatus(CAN1,CAN_IT_LEC))
    {
        CAN_ClearITPendingBit(CAN1,CAN_IT_LEC);
        //DEBUG_PRINTF("LEC\r\n");
    }

    if(CAN_GetITStatus(CAN1,CAN_IT_ERR))
    {
        CAN_ClearITPendingBit(CAN1,CAN_IT_ERR);
        //DEBUG_PRINTF("ERR\r\n");
    }
    
    drv_can_init();
}
void CAN1_RX1_IRQHandler(void)
{
    CAN_ITConfig(CAN1,  CAN_IT_FMP1, DISABLE);

    CAN_Receive(CAN1, CAN_FIFO1, &RxMessage);
    //if((RxMessage.ExtId == drv_can_info.rec_ex_can_id) && (RxMessage.IDE == CAN_ID_EXT))

    if((RxMessage.StdId == drv_can_info.ptc_std_identify) && (RxMessage.IDE == CAN_ID_STD))
    {
        for(uint8_t i = 0; i < RxMessage.DLC; i++)
        {
            //DEBUG_PRINTF("%02x ", RxMessage.Data[i]);
            if(queue_full(&get_can_info()->rx_queue) == FALSE)
            {
                write_byte_queue(&get_can_info()->rx_queue, RxMessage.Data[i]);
                //datalink_port_pack_receive();
            }
                
        }
    }

    CAN_ITConfig(CAN1,  CAN_IT_FMP1, ENABLE);
}


uint32_t shell_can_frame_send(uint32_t argc, char **argv)
{
    TxMessage.DLC = 8;

    for(uint8_t idx = 0; idx < 8; idx++)
        TxMessage.Data[idx] = idx;

    CAN_Transmit(CAN1, &TxMessage);

    return 0;
}

#else
uint32_t shell_can_frame_send(uint32_t argc, char **argv){return 0;}
void drv_can_disable(void){}
void can_transmit_isr_callback(void){}


#endif
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__





void drv_can_init(void);
void drv_can_disable(void);
void can_transmit_isr_callback(void);

uint16_t drv_can_puts(const uint8_t *src, uint16_t len);
uint32_t shell_can_frame_send(uint32_t argc, char **argv);


#endif

/*
 * Copyright(C) 2015.
 *
 * @File middlewares/mcu_periph/uart.c
 *
 * @Description:
 * 	   uart peripheral.
 *
 *
 */

/* Includes ------------------------------------------------------------------*/
#define DEF_DEBUG_TRACE
#define DEF_DEBUG_MSG
#define DEF_DEBUG_PRINTF
#define DEF_DEBUG_WARNING
#define DEF_DEBUG_ERROR
#include "debug.h"
#include "config_mcu_periph.h"

#include "can.h"
#include "drv_can.h"
#include "usb_vcp_hw.h"
#include "dasi_str.h"
#include "usb_vcp_interface.h"
#include "key.h"
#include "drv_sys_time.h"
#include "uart.h"
#include "sys_config.h"

uint8_t  can_send_flag = 0;




#define CAN_TX_BUFFER_SIZE 800
#define CAN_RX_BUFFER_SIZE 512
uint8_t can_tx_buf[CAN_TX_BUFFER_SIZE];
uint8_t can_rx_buf[CAN_RX_BUFFER_SIZE];


static can_t can_info= {
    .tx_buf = can_tx_buf,
    .rx_buf = can_rx_buf,
    .tx_buf_size = CAN_TX_BUFFER_SIZE,
    .rx_buf_size = CAN_RX_BUFFER_SIZE,

    .tx_running = FALSE,
    .can_error  = FALSE,
};

can_t* get_can_info(void)
{
    return &can_info;
}

#ifdef  ENABLE_CAN

void can_init(void)
{
    drv_can_init();
    init_queue(&can_info.rx_queue, can_info.rx_buf, can_info.rx_buf_size);
    init_queue(&can_info.tx_queue, can_info.tx_buf, can_info.tx_buf_size);
}

void can_disable(void)
{
	drv_can_disable();
}

void can_rx_queue_clear(void)
{
    clear_queue(&can_info.rx_queue);
}

uint16_t can_rx_queue_len(void)
{
    return queue_length(&can_info.rx_queue);
}


uint16_t can_read(uint8_t* buf, uint16_t read_len)
{
	return read_block_queue(buf, &can_info.rx_queue, read_len);
}



uint16_t can_puts(const uint8_t *src, uint16_t len)
{
    return drv_can_puts(src, len);
}

static void can_func(void)
{
    usb_hot_change(USB_FUNC_NOT_INIT);
    
    bsp_delinitUsb();
    
    can_init();

    DEBUG_TRACE();
}

static void usb_func(void)
{
    can_disable();
    usb_hot_change(USB_FUNC_FOR_VCP);
    DEBUG_TRACE();
}

uint8_t last_func = CAN_FUNC;

void can_or_usb_cut_func(uint8_t func)
{
    if(func == USB_FUNC)
    {
        usb_func();
        can_send_flag = 0;
        last_func = USB_FUNC;
    }
    else if(func == CAN_FUNC)
    {
        can_func();
        can_send_flag = 1;
        last_func = CAN_FUNC;
    }
    else
        DEBUG_ERROR("func:%d\r\n", func);
}

void can_or_usb_cut_ontick(void)
{
    static uint8_t init_flag = 0;
    if(init_flag == 0)
    {
        if(get_sys_config()->fcu_type == FCU_EFY)
            can_or_usb_cut_func(CAN_FUNC);
            
        init_flag = 1;
    }
    
    if(get_sys_config()->fcu_type != FCU_EFY)
        return;
        
    static uint32_t last_long_key_time = 0;

    if(init_flag == 1)
    {
        last_long_key_time = get_sys_time_ms();
        if(get_key_real_key_sta(KEY_02) == KeyLongDown)
            init_flag = 2;
    }
    else if(init_flag == 2)
    {
        if(get_key_cur_key_sta(KEY_02) != KeyLongDown)
        {
            init_flag = 1;
            return;
        }

        if((get_sys_time_ms() - last_long_key_time) >= 5000)
        {
            if(last_func == CAN_FUNC)
                can_or_usb_cut_func(USB_FUNC);
            //else if(last_func == USB_FUNC)
            //    can_or_usb_cut_func(CAN_FUNC);
            
            init_flag = 1;
        }
    }
        
}


uint32_t shell_can_init(uint32_t argc, char **argv)
{
    can_or_usb_cut_func(CAN_FUNC);    
    return 0;
}


uint32_t shell_can_or_usb(uint32_t argc, char **argv)
{
    u8 cmd = str_convert_hex(argv[0], 2);

    if(cmd == 0)
    {
        usb_hot_change(USB_FUNC_NOT_INIT);
        
        bsp_delinitUsb();
        
        can_init();

        can_send_flag = 1;

            
		DEBUG_MSG("usb close, can open\r\n");
    }
    else
    {
        can_disable();
        usb_hot_change(USB_FUNC_FOR_VCP); 

		DEBUG_MSG("usb open, can close\r\n");
    }
    return 0;
}


#else


uint32_t shell_can_init(uint32_t argc, char **argv){return 0;}

void can_or_usb_cut_func(uint8_t func){}
void can_or_usb_cut_ontick(void){}
void can_rx_queue_clear(void){}
uint16_t can_rx_queue_len(void){return 0;}
uint16_t can_read(uint8_t* buf, uint16_t read_len){	return 0;}
uint16_t can_puts(const uint8_t *src, uint16_t len){return 0;}

uint32_t shell_can_or_usb(uint32_t argc, char **argv){return 0;}



#endif





/*
 * Copyright(C) 2015.
 *
 * @File middlewares/mcu_periph/uart.h
 *
 * @Description:
 * 	   uart peripheral.
 *
 *
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__




#include "dsi_types.h"
#include "ring_queue.h"
#include "drv_can.h"
#include "can.h"


typedef struct
{
    uint8_t *tx_buf;
    uint8_t *rx_buf;
    uint16_t tx_buf_size;
    uint16_t rx_buf_size;

    struct _ring_queue tx_queue;
    struct _ring_queue rx_queue;

    bool_t  tx_running;
    bool_t  can_error;
} can_t;

enum
{
    CAN_FUNC,
    USB_FUNC,
};


can_t* get_can_info(void);
void can_init(void);
void can_disable(void);
void can_rx_queue_clear(void);
uint16_t can_rx_queue_len(void);
uint16_t can_read(uint8_t* buf, uint16_t read_len);
uint16_t can_puts(const uint8_t *src, uint16_t len);
void can_or_usb_cut_ontick(void);
uint32_t shell_can_init(uint32_t argc, char **argv);
uint32_t shell_can_or_usb(uint32_t argc, char **argv);
void can_or_usb_cut_func(uint8_t func);




#endif 
/

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值