#ifndef _TYPE_H_
#define _TYPE_H_
/* exact-width signed integer types */
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed __int64 int64_t;
/* exact-width unsigned integer types */
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned int size_t;
typedef unsigned __int64 uint64_t;
#ifndef NULL
#ifdef __cplusplus // EC++
#define NULL 0
#else
#define NULL ((void *) 0)
#endif
#endif
#ifndef boolean
typedef uint8_t boolean;
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#endif /* _TYPE_H_ */
#ifndef _CAN_QUEUE_H_
#define _CAN_QUEUE_H_
#include "stm32f10x_can.h"
#include "type.h"
#define CAN_TX_SIZE 0x25
typedef enum
{
CAN_ERROR = 0,
CAN_OK = 1,
CAN_BUSY = 2,
} can_queue_status_t;
typedef CanTxMsg can_frame_t;
typedef struct
{
uint32_t write;
uint32_t read;
boolean is_full;
uint32_t length;
can_frame_t *frame;
} can_queue_t;
extern can_queue_t can_queue_send;
void CanQueueInit(void);
uint8_t CanQueueRead(can_queue_t *q, can_frame_t *frame);
uint8_t CanQueueWrite(can_queue_t *q, can_frame_t *frame);
#endif /* _CAN_QUEUE_H_ */
#include "can_queue.h"
#include
#include "debug.h"
static can_frame_t tx[CAN_TX_SIZE] = {0};
can_queue_t can_queue_send =
{
0,
0,
FALSE,
CAN_TX_SIZE,
tx
};
const can_frame_t frame_init =
{
0,
0,
0,
0,
0,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};
static void can_queue_init(can_queue_t *q, can_frame_t *frame, uint8_t length)
{
uint8_t i;
q->write = 0;
q->read = 0;
q->is_full = FALSE;
q->length = length;
q->frame = frame;
for(i = 0; i < length; ++i)
{
q->frame[i] = frame_init;
}
}
static can_frame_t *can_frame_malloc(can_queue_t *q)
{
can_frame_t *frame;
if(NULL == q)
{
return NULL;
}
if(TRUE == q->is_full)
{
return NULL;
}
frame = &(q->frame[q->write++]);
if(q->write >= q->length)
{
q->write = 0;
}
if(q->write == q->read)
{
q->is_full = TRUE;
}
*frame = frame_init;
return frame;
}
static void can_frame_clear(can_frame_t *frame)
{
can_frame_t *dst = frame;
dst->StdId = 0;
dst->DLC = 0;
dst->IDE = CAN_Id_Standard;
dst->RTR = CAN_RTR_Data;
memset(dst->Data, 0, 8);
}
static void can_frame_copy(can_frame_t *dst, can_frame_t *src)
{
can_frame_t *dst_tmp = dst, *src_tmp = src;
dst_tmp->StdId = src_tmp->StdId;
dst_tmp->DLC = src_tmp->DLC;
dst_tmp->IDE = src_tmp->IDE;
dst_tmp->RTR = src_tmp->RTR;
memcpy(dst_tmp->Data, src_tmp->Data, 8);
}
uint8_t CanQueueRead(can_queue_t *q, can_frame_t *frame)
{
uint8_t status = CAN_ERROR;
if(NULL == q)
{
return CAN_ERROR;
}
if((q->read != q->write) || (q->is_full == TRUE))
{
can_frame_copy(frame, &q->frame[q->read]);
can_frame_clear(&q->frame[q->read]);
q->read += 1;
if(q->read >= q->length)
{
q->read = 0;
}
q->is_full = FALSE;
status = CAN_OK;
}
return status;
}
uint8_t CanQueueWrite(can_queue_t *q, can_frame_t *frame)
{
can_frame_t *dst;
dst = can_frame_malloc(q);
if(NULL == dst)
{
return CAN_ERROR;
}
can_frame_copy(dst, frame);
return CAN_OK;
}
void CanQueueInit(void)
{
can_queue_init(&can_queue_send, tx, CAN_TX_SIZE);
}
#ifndef _CAN_H_
#define _CAN_H_
#include "can_queue.h"
#include "type.h"
#include "debug.h"
void CANInit(void);
void CanSendMsg(can_frame_t *frame);
#ifdef CONFIG_CAN
void can_general(void);
#endif
#endif /* _CAN_H_ */
#include "can.h"
#include "stm32f10x_can.h"
#include "stm32f10x.h"
#include "delay.h"
#include "target.h"
#include "string.h"
static void can_gpio_clk_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE);
}
static void can_gpio_init(void)
{
can_gpio_clk_init();
CAN_TX_CONFIG();
CAN_RX_CONFIG();
}
static void can_mode_init(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_DeInit(CAN_CHANNEL);
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = ENABLE ;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = ENABLE ;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // baund = APB1/((tbs1+1+tbs2+1+1)*brp) --- APB1 = 36K
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 8;
CAN_Init(CAN_CHANNEL, &CAN_InitStructure);
}
static void can_nvic_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
CAN_ITConfig(CAN_CHANNEL, CAN_IT_FMP0, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void can_filter_init(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void CANInit(void)
{
can_gpio_init();
can_mode_init();
can_filter_init();
can_nvic_init();
}
void CanSendMsg(can_frame_t *frame)
{
int i;
CAN_Transmit(CAN_CHANNEL, frame);
for(i=0;i<1000;++i);
}
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
CanTxMsg TxMessage;
int i = 0;
CAN_Receive(CAN_CHANNEL, 0, &RxMessage);
#if 1
TxMessage.StdId = 0x101;
TxMessage.IDE = CAN_Id_Standard;
TxMessage.RTR = CAN_RTR_Data;
TxMessage.DLC = RxMessage.DLC;
for(i = 0; i < TxMessage.DLC; i++)
{
TxMessage.Data[i] = RxMessage.Data[i];
}
CanQueueWrite(&can_queue_send, &TxMessage);
#endif
}
#ifdef CONFIG_CAN
void can_general(void)
{
int i;
can_frame_t frame;
uint8_t buffer[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
frame.StdId = 0x11;
frame.DLC = 6;
frame.IDE = CAN_Id_Standard;
frame.RTR = CAN_RTR_Data;
memcpy(frame.Data, buffer, 6);
//CanQueueWrite(&can_queue_send, &frame);
for(i = 0; i < 7000; ++i);
}
#endif