#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
/