|
|
@@ -5,8 +5,9 @@
|
|
|
|
|
|
#define CAN_FILTER_MAX 16
|
|
|
|
|
|
-#define PDEBUG(fmt,args...) //printf("[DEG] " fmt, ##args)
|
|
|
-#define PERROR(fmt,args...) printf("[ERR] " fmt, ##args)
|
|
|
+#define PDEBUG(fmt,args...) //printf("[DEG] " fmt, ##args)
|
|
|
+#define PWARN(fmt,args...) //printf("[WRN] " fmt, ##args)
|
|
|
+#define PERROR(fmt,args...) printf("[ERR] " fmt, ##args)
|
|
|
|
|
|
#define CAN_CALC_MAX_ERROR 50
|
|
|
|
|
|
@@ -79,6 +80,17 @@
|
|
|
#define RSTAT_FULL (3 << 0) /*!< full (stays set in case of overflow – for overflow signaling see ROV) */
|
|
|
#define RSTAT_NO_EMPTY_MASK (3 << 0)
|
|
|
|
|
|
+/**************************** 总线错误类型 *********************************/
|
|
|
+#define CAN_BE_BITOFF (5U)
|
|
|
+#define CAN_BE_TYPE_MASK (7U << CAN_BE_BITOFF)
|
|
|
+
|
|
|
+#define CAN_BE_TYPE_NO_ERROR (0U << CAN_BE_BITOFF) /*!< no error */
|
|
|
+#define CAN_BE_TYPE_BIT_ERROR (1U << CAN_BE_BITOFF) /*!< bit error */
|
|
|
+#define CAN_BE_TYPE_FORM_ERROR (2U << CAN_BE_BITOFF) /*!< form error */
|
|
|
+#define CAN_BE_TYPE_STUFF_ERROR (3U << CAN_BE_BITOFF) /*!< stuff error */
|
|
|
+#define CAN_BE_TYPE_ACKNOWLEDGEMENT_ERROR (4U << CAN_BE_BITOFF) /*!< acknowledgement error */
|
|
|
+#define CAN_BE_TYPE_CRC_ERROR (5U << CAN_BE_BITOFF) /*!< crc error */
|
|
|
+#define CAN_BE_TYPE_OTHER_ERROR (6U << CAN_BE_BITOFF) /*!< other error */
|
|
|
|
|
|
/************************* TTCFG 寄存器位定义 ******************************/
|
|
|
#define CAN_TTCFG_TTEN (1 << 0)
|
|
|
@@ -104,27 +116,18 @@ struct can_bittiming{
|
|
|
u8 brp;
|
|
|
};
|
|
|
|
|
|
-struct can_databittiming{
|
|
|
- u8 prop_seg;
|
|
|
- u8 phase_seg1;
|
|
|
- u8 phase_seg2;
|
|
|
- u8 sjw;
|
|
|
- u8 brp;
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
typedef struct {
|
|
|
u32 id;
|
|
|
u32 ctl;
|
|
|
- u32 dat32[72/4 - 2];
|
|
|
+ u32 dat32[16];
|
|
|
}CAN_TBuf_t;
|
|
|
|
|
|
typedef struct {
|
|
|
u32 id;
|
|
|
u32 ctl;
|
|
|
union{
|
|
|
- u32 dat32[80/4 - 2];
|
|
|
- uint8_t dat8[80 - 8];
|
|
|
+ u32 dat32[16];
|
|
|
+ uint8_t dat8[64];
|
|
|
};
|
|
|
}CAN_RBuf_t;
|
|
|
|
|
|
@@ -133,16 +136,13 @@ typedef struct
|
|
|
{
|
|
|
CanMode_t Mode;
|
|
|
struct can_bittiming BitTiming;
|
|
|
- struct can_databittiming DataBitTiming; // FD
|
|
|
+ struct can_bittiming DataBitTiming;
|
|
|
u8 tdc_en;
|
|
|
u8 sspoff;
|
|
|
u8 FD_En;
|
|
|
- u8 ttcan;
|
|
|
- u8 t_presc; // ttcan use
|
|
|
} CAN_InitTypeDef;
|
|
|
|
|
|
|
|
|
-
|
|
|
#define CAN_RX_BUF_NUM 16
|
|
|
#define CAN_PTB_TX_BUF_NUM 16
|
|
|
#define CAN_STB_TX_BUF_NUM 16
|
|
|
@@ -156,12 +156,17 @@ ListItem_t canStbTxListItem[CAN_NUM][CAN_STB_TX_BUF_NUM];
|
|
|
|
|
|
static CanPort_t *pxCanPort[CAN_NUM] = {NULL};
|
|
|
static CAN_InitTypeDef CanInitValue[CAN_NUM];
|
|
|
-static CAN_FilterInitTypeDef CanFilterInitValue[CAN_NUM];
|
|
|
-static int nCanFilterEnable[CAN_NUM];
|
|
|
-
|
|
|
-/********** can src clock 40M **********/
|
|
|
-const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
- /*********** 10M ************/
|
|
|
+static CAN_FilterInitTypeDef CanFilterInitValue[CAN_NUM][CAN_FILTER_MAX];
|
|
|
+static u8 nCanFilterEnable[CAN_NUM][CAN_FILTER_MAX];
|
|
|
+
|
|
|
+/**
|
|
|
+ * can src clock 40M
|
|
|
+ *
|
|
|
+ * baud = can_src_clk / brp / (1 + prop_seg + phase_seg1 + phase_seg2)
|
|
|
+ * sampling point = (1 + prop_seg + phase_seg1) / (1 + prop_seg + phase_seg1 + phase_seg2)
|
|
|
+ */
|
|
|
+const static struct can_bittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
+ /*********** 10M 75% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 1,
|
|
|
@@ -169,7 +174,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 1,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 8M ************/
|
|
|
+ /*********** 8M 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 2,
|
|
|
@@ -177,7 +182,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 1,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 5M ************/
|
|
|
+ /*********** 5M 75% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 4,
|
|
|
@@ -185,7 +190,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 2,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 4M ***********/
|
|
|
+ /*********** 4M 80% ***********/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 6,
|
|
|
@@ -193,7 +198,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 2,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 2M ***********/
|
|
|
+ /*********** 2M 80% ***********/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 14,
|
|
|
@@ -201,7 +206,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 4,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 1M ***********/
|
|
|
+ /*********** 1M 80% ***********/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 30,
|
|
|
@@ -209,7 +214,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 8,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 800K ************/
|
|
|
+ /*********** 800K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 18,
|
|
|
@@ -217,7 +222,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 5,
|
|
|
.brp = 2,
|
|
|
},
|
|
|
- /*********** 500K ************/
|
|
|
+ /*********** 500K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 62,
|
|
|
@@ -225,7 +230,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 16,
|
|
|
.brp = 1,
|
|
|
},
|
|
|
- /*********** 250K ************/
|
|
|
+ /*********** 250K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 62,
|
|
|
@@ -233,7 +238,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 16,
|
|
|
.brp = 2,
|
|
|
},
|
|
|
- /*********** 125K ************/
|
|
|
+ /*********** 125K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 62,
|
|
|
@@ -241,7 +246,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 16,
|
|
|
.brp = 4,
|
|
|
},
|
|
|
- /*********** 100K ************/
|
|
|
+ /*********** 100K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 62,
|
|
|
@@ -249,7 +254,7 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 16,
|
|
|
.brp = 5,
|
|
|
},
|
|
|
- /*********** 50K ************/
|
|
|
+ /*********** 50K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
.phase_seg1 = 62,
|
|
|
@@ -257,85 +262,16 @@ const static struct can_databittiming canfd_baud_param_tab[CANFDBaudSelMax] = {
|
|
|
.sjw = 16,
|
|
|
.brp = 10,
|
|
|
},
|
|
|
- /*********** 40K ************/
|
|
|
+ /*********** 40K 80% ************/
|
|
|
{
|
|
|
.prop_seg = 1,
|
|
|
- .phase_seg1 = 32,
|
|
|
- .phase_seg2 = 16,
|
|
|
+ .phase_seg1 = 38,
|
|
|
+ .phase_seg2 = 10,
|
|
|
.sjw = 16,
|
|
|
.brp = 20,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-/********** can src clock 40M **********/
|
|
|
-const static struct can_bittiming can_baud_param_tab[CANBaudSelMax] = {
|
|
|
- /*********** 1M ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 2,
|
|
|
- },
|
|
|
- /*********** 800K ************/
|
|
|
- {
|
|
|
- .prop_seg = 9,
|
|
|
- .phase_seg1 = 10,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 2,
|
|
|
- },
|
|
|
- /*********** 500K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 4,
|
|
|
- },
|
|
|
- /*********** 250K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 8,
|
|
|
- },
|
|
|
- /*********** 125K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 16,
|
|
|
- },
|
|
|
- /*********** 100K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 20,
|
|
|
- },
|
|
|
- /*********** 50K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 40,
|
|
|
- },
|
|
|
- /*********** 40K ************/
|
|
|
- {
|
|
|
- .prop_seg = 5,
|
|
|
- .phase_seg1 = 9,
|
|
|
- .phase_seg2 = 5,
|
|
|
- .sjw = 1,
|
|
|
- .brp = 50,
|
|
|
- },
|
|
|
-};
|
|
|
-
|
|
|
/* map the sanitized data length to an appropriate data length code */
|
|
|
static u8 can_len2dlc(u8 len)
|
|
|
{
|
|
|
@@ -385,7 +321,7 @@ u8 can_set_reset_mode(CANFD_TypeDef* CANx)
|
|
|
|
|
|
static int canfd_device_driver_bittime_configuration(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct){
|
|
|
struct can_bittiming *bt = &CAN_InitStruct->BitTiming;
|
|
|
- struct can_databittiming *dbt = &CAN_InitStruct->DataBitTiming;
|
|
|
+ struct can_bittiming *dbt = &CAN_InitStruct->DataBitTiming;
|
|
|
|
|
|
if(!(CANx->CFG_STAT & CAN_CFG_STAT_RESET)){
|
|
|
//netdev_alert(ndev, "Not in reset mode, cannot set bit timing\n");
|
|
|
@@ -398,10 +334,6 @@ static int canfd_device_driver_bittime_configuration(CANFD_TypeDef* CANx, CAN_In
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if(CAN_InitStruct->ttcan){
|
|
|
- CANx->TTCFG |= (CAN_InitStruct->t_presc & 0x3) << 1;
|
|
|
- }
|
|
|
-
|
|
|
CANx->S_SEG_1 = (bt->phase_seg1+bt->prop_seg-1);
|
|
|
CANx->S_SEG_2 = (bt->phase_seg2-1);
|
|
|
CANx->S_SJW = (bt->sjw-1);
|
|
|
@@ -412,7 +344,7 @@ static int canfd_device_driver_bittime_configuration(CANFD_TypeDef* CANx, CAN_In
|
|
|
PERROR("fast bittime configuration is incorrect\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- CANx->TDC = CAN_InitStruct->sspoff & 0x3f;
|
|
|
+ CANx->TDC = CAN_InitStruct->sspoff & 0x7f;
|
|
|
if(CAN_InitStruct->tdc_en){
|
|
|
CANx->TDC |= (1<<7);
|
|
|
}
|
|
|
@@ -427,7 +359,7 @@ static int canfd_device_driver_bittime_configuration(CANFD_TypeDef* CANx, CAN_In
|
|
|
}
|
|
|
|
|
|
|
|
|
-u8 CAN_Init(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
|
|
|
+static u8 CAN_Init(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
|
|
|
{
|
|
|
u8 InitStatus = CAN_InitStatus_Success;
|
|
|
|
|
|
@@ -452,13 +384,13 @@ u8 CAN_Init(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
|
|
|
|
|
|
canfd_device_driver_bittime_configuration(CANx, CAN_InitStruct);/*set S_seg_1 S_Seg_2 S_SJW S_PRESC */
|
|
|
|
|
|
+ CANx->LIMIT = 0;
|
|
|
+
|
|
|
/*set Almost Full Warning Limit*/
|
|
|
- CANx->LIMIT |= 0x40;
|
|
|
+ CANx->LIMIT |= 0x80; // 3*8 = 24
|
|
|
|
|
|
/*Programmable Error Warning Limit = (EWL+1)*8. Set EWL=11->Error Warning=96 */
|
|
|
CANx->LIMIT |= 0X0B;
|
|
|
- /*the start state*/
|
|
|
- //priv->can.state=CAN_STATE_ERROR_ACTIVE;
|
|
|
/*interrupts enable*/
|
|
|
CANx->RTIE = CAN_IER_ALL;
|
|
|
/*Error Interrupts enable(Error Passive and Bus Error)*/
|
|
|
@@ -486,10 +418,6 @@ u8 CAN_Init(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if(CAN_InitStruct->ttcan){
|
|
|
- CANx->TTCFG |= CAN_TTCFG_TTEN;
|
|
|
- }
|
|
|
-
|
|
|
return InitStatus;
|
|
|
}
|
|
|
|
|
|
@@ -497,20 +425,13 @@ u8 CAN_Init(CANFD_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
|
|
|
/*This part could also be removed, when only one mode is used*/
|
|
|
static int set_canfd_xmit_mode(CANFD_TypeDef* CANx, CAN_TX_Mode tx_mode){
|
|
|
switch(tx_mode){
|
|
|
- /*
|
|
|
- case XMIT_FULL:
|
|
|
- //CANx->TCTRL |= CAN_TCTRL_TTTBM;
|
|
|
- PDEBUG( "Full can mode\n");
|
|
|
- break;
|
|
|
- */
|
|
|
-
|
|
|
case XMIT_STB_FIFO:
|
|
|
CANx->TCTRL &= ~CAN_TCTRL_TTTBM;
|
|
|
CANx->TCTRL &= ~CAN_TCTRL_TSMODE;
|
|
|
CANx->TCMD |= CAN_TCMD_TBSEL;
|
|
|
PDEBUG( "FIFO mode\n");
|
|
|
break;
|
|
|
- case XMIT_SEP_PRIO:
|
|
|
+ case XMIT_STB_PRIO:
|
|
|
CANx->TCTRL &= ~CAN_TCTRL_TTTBM;
|
|
|
CANx->TCTRL |= CAN_TCTRL_TSMODE;
|
|
|
CANx->TCMD |= CAN_TCMD_TBSEL;
|
|
|
@@ -552,7 +473,7 @@ static int CAN_PTB_Tran(CANFD_TypeDef* CANx, CanMsg* TxMessage)
|
|
|
if (TxMessage->BRS) /*CANFD_BRS=0x01*/
|
|
|
ctl |= CAN_FD_SET_BRS_MASK;
|
|
|
|
|
|
- for(i=0; i<TxMessage->DLC/4; i++){
|
|
|
+ for (i = 0; i < (TxMessage->DLC + 3) / 4; i++) {
|
|
|
pTbuf->dat32[i] = *((u32 *)(TxMessage->Data + i*4));
|
|
|
}
|
|
|
PDEBUG( "TCMD is 0x%02x after writing data into resiger\n",CANx->TCMD);
|
|
|
@@ -627,7 +548,7 @@ static int CAN_STB_FIFO_Tran(CANFD_TypeDef* CANx, CanMsg* TxMessage)
|
|
|
if (TxMessage->BRS) /*CANFD_BRS=0x01*/
|
|
|
ctl |= CAN_FD_SET_BRS_MASK;
|
|
|
|
|
|
- for(i=0; i<TxMessage->DLC/4; i++){
|
|
|
+ for (i = 0; i < (TxMessage->DLC + 3) / 4; i++) {
|
|
|
pTbuf->dat32[i] = *((u32 *)(TxMessage->Data + i*4));
|
|
|
}
|
|
|
PDEBUG( "TCMD is 0x%02x after writing data into resiger\n",CANx->TCMD);
|
|
|
@@ -681,20 +602,10 @@ static int CAN_STB_FIFO_Tran(CANFD_TypeDef* CANx, CanMsg* TxMessage)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int CAN_TTCAN_Tran(CANFD_TypeDef* CANx, CanMsg* TxMessage)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
-
|
|
|
- CANx->TCTRL |= CAN_TCTRL_TTTBM;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
static void can_reinit(CanPort_t *cap)
|
|
|
{
|
|
|
+ int i;
|
|
|
+
|
|
|
if (cap->id == CAN_ID0){
|
|
|
MCU_SYSCTRL->V6_RST_CTL &= ~(1 << 0);
|
|
|
TIMER_Udelay(10);
|
|
|
@@ -709,8 +620,10 @@ static void can_reinit(CanPort_t *cap)
|
|
|
|
|
|
CAN_Init(cap->pcan, &CanInitValue[cap->id]);
|
|
|
|
|
|
- if (nCanFilterEnable[cap->id]) {
|
|
|
- vCanSetFilter(cap, CanFilterInitValue[cap->id]);
|
|
|
+ for (i = 0; i < CAN_FILTER_MAX; i++) {
|
|
|
+ if (nCanFilterEnable[cap->id][i]) {
|
|
|
+ vCanSetFilter(cap, CanFilterInitValue[cap->id][i]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -839,36 +752,46 @@ static int can_rx(CANFD_TypeDef *CANx, CanMsg *RxMessage){
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int CAN_RX(CANFD_TypeDef *CANx, CanMsg *RxMessage)
|
|
|
+static int CAN_RX(CanPort_t *pCanPort)
|
|
|
{
|
|
|
- u8 rx_status=0,control=0;
|
|
|
- CAN_RBuf_t *pRBuf = (CAN_RBuf_t *)(CANx->RBUF_RTS);
|
|
|
- control = pRBuf->ctl & 0xff;
|
|
|
- rx_status = CANx->RCTRL;
|
|
|
- while((rx_status & RSTAT_NO_EMPTY_MASK)){
|
|
|
- ( control & CAN_FD_SET_EDL_MASK) ? (canfd_rx(CANx, RxMessage)) : (can_rx(CANx, RxMessage));
|
|
|
- rx_status = CANx->RCTRL;
|
|
|
- PDEBUG( "rx-status is 0x%02x\n",rx_status);
|
|
|
- PDEBUG( "rx-status is 0x%08x\n",*((u32 *) CANx->CFG_STAT));
|
|
|
-
|
|
|
+ CanMsg RxMessage;
|
|
|
+ CAN_RBuf_t *pRBuf;
|
|
|
+ u8 control=0;
|
|
|
+ int msg_cnt = 0;
|
|
|
+ CANFD_TypeDef *CANx = pCanPort->pcan;
|
|
|
+
|
|
|
+ while (CANx->RCTRL & RSTAT_NO_EMPTY_MASK) {
|
|
|
+ memset(&RxMessage, 0, sizeof(CanMsg));
|
|
|
+ pRBuf = (CAN_RBuf_t *)(CANx->RBUF_RTS);
|
|
|
+ control = pRBuf->ctl & 0xff;
|
|
|
+ (control & CAN_FD_SET_EDL_MASK) ? (canfd_rx(CANx, &RxMessage)) : (can_rx(CANx, &RxMessage));
|
|
|
+ if (!listLIST_IS_EMPTY(&pCanPort->rxFreeList)) {
|
|
|
+ ListItem_t *item = listGET_HEAD_ENTRY(&pCanPort->rxFreeList);
|
|
|
+ memcpy((void*)listGET_LIST_ITEM_VALUE(item), &RxMessage, sizeof(CanMsg));
|
|
|
+ uxListRemove(item);
|
|
|
+ vListInsertEnd(&pCanPort->rxRevList, item);
|
|
|
+ xSemaphoreGiveFromISR(pCanPort->xRev, 0);
|
|
|
+ } else {
|
|
|
+ PWARN("rl full!\n");
|
|
|
+ }
|
|
|
+ msg_cnt++;
|
|
|
}
|
|
|
- return 0;
|
|
|
+
|
|
|
+ return msg_cnt;
|
|
|
}
|
|
|
|
|
|
-void CAN0_IRQHandler(void)
|
|
|
+static int CAN_IRQHandler(CanPort_t *pCanPort)
|
|
|
{
|
|
|
uint8_t isr=0,errint=0;
|
|
|
- CanPort_t *pCanPort = pxCanPort[CAN_ID0];
|
|
|
CANFD_TypeDef *CANx = NULL;
|
|
|
- CanMsg RxMessage = {0};
|
|
|
-
|
|
|
- // printf("CAN0_IRQHandler \r\n");
|
|
|
+ int rx_msg_num = 0;
|
|
|
|
|
|
+ // printf("CAN%d_IRQHandler \r\n", pCanPort->id);
|
|
|
if(pCanPort){
|
|
|
CANx = pCanPort->pcan;
|
|
|
isr = CANx->RTIF;
|
|
|
errint= CANx->ERRINT;
|
|
|
+
|
|
|
if(isr & CAN_IFR_TPIF){
|
|
|
xQueueSendFromISR(pCanPort->tx_done, NULL, 0);
|
|
|
}
|
|
|
@@ -876,33 +799,24 @@ void CAN0_IRQHandler(void)
|
|
|
xQueueSendFromISR(pCanPort->Stb_tx_done, NULL, 0);
|
|
|
}
|
|
|
if(isr & CAN_IFR_ROIF){
|
|
|
- PERROR("CAN0 ROIF! \r\n");
|
|
|
+ PERROR("CAN%d ROIF! \r\n", pCanPort->id);
|
|
|
//can_reinit(pCanPort);
|
|
|
}
|
|
|
if(isr & CAN_IFR_EIF){
|
|
|
- PERROR("CAN0 EIF! \r\n");
|
|
|
+ PERROR("CAN%d EIF! \r\n", pCanPort->id);
|
|
|
//can_reinit(pCanPort);
|
|
|
}
|
|
|
|
|
|
if(isr & (CAN_IFR_RF | CAN_IFR_RFIF | CAN_IFR_RAFIF)){
|
|
|
- CAN_RX(CANx, &RxMessage);
|
|
|
- if (!listLIST_IS_EMPTY(&pCanPort->rxFreeList)) {
|
|
|
- ListItem_t *item = listGET_HEAD_ENTRY(&pCanPort->rxFreeList);
|
|
|
- memcpy((void*)listGET_LIST_ITEM_VALUE(item), &RxMessage, sizeof(CanMsg));
|
|
|
- uxListRemove(item);
|
|
|
- vListInsertEnd(&pCanPort->rxRevList, item);
|
|
|
- xSemaphoreGiveFromISR(pCanPort->xRev, 0);
|
|
|
- } else {
|
|
|
-
|
|
|
- }
|
|
|
+ rx_msg_num = CAN_RX(pCanPort);
|
|
|
}
|
|
|
|
|
|
- if(CANx->CFG_STAT & 0x01){
|
|
|
- PERROR("BUSOFF!\n");
|
|
|
+ if(CANx->CFG_STAT & 0x01) {
|
|
|
+ PERROR("************************ BUSOFF! **************************\n");
|
|
|
}
|
|
|
|
|
|
if(errint & CAN_EIFR_EWARN){ // 错误计数器值超过EWL时会产生该中断
|
|
|
- PERROR("CAN_EIFR_EWARN! TECNT:0x%x RECNT:0x%x \r\n",CANx->TECNT, CANx->RECNT);
|
|
|
+ PERROR("CAN_EIFR_EWARN! TECNT:0x%x RECNT:0x%x \r\n",CANx->TECNT, CANx->RECNT);
|
|
|
}
|
|
|
if(errint & CAN_EIFR_EPASS){ // 错误被动模式激活,即错误计数 >127 此位为1
|
|
|
PERROR("CAN_EIFR_EPASS! \r\n");
|
|
|
@@ -910,84 +824,42 @@ void CAN0_IRQHandler(void)
|
|
|
if(errint & CAN_EIFR_EPIF){ // 错误计数器向上或向下越过127都会产生该中断
|
|
|
PERROR("CAN_EIFR_EPIF! \r\n");
|
|
|
}
|
|
|
- if(errint & CAN_EIFR_ALIF){
|
|
|
+ if(errint & CAN_EIFR_ALIF){ // 仲裁失败
|
|
|
PERROR("CAN_EIFR_ALIF! \r\n");
|
|
|
}
|
|
|
if(errint & CAN_EIFR_BEIF){ // 总线错误
|
|
|
- PERROR("CAN_EIFR_BEIF! \r\n");
|
|
|
+ PERROR("CAN_EIFR_BEIF! ECODE=0x%x\r\n", CANx->EALCAP);
|
|
|
+ switch (CANx->EALCAP & CAN_BE_TYPE_MASK) {
|
|
|
+ case CAN_BE_TYPE_BIT_ERROR:
|
|
|
+ break;
|
|
|
+ case CAN_BE_TYPE_FORM_ERROR:
|
|
|
+ break;
|
|
|
+ case CAN_BE_TYPE_STUFF_ERROR:
|
|
|
+ break;
|
|
|
+ case CAN_BE_TYPE_ACKNOWLEDGEMENT_ERROR:
|
|
|
+ break;
|
|
|
+ case CAN_BE_TYPE_CRC_ERROR:
|
|
|
+ break;
|
|
|
+ case CAN_BE_TYPE_OTHER_ERROR:
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
CANx->RTIF = isr;
|
|
|
CANx->ERRINT = errint;
|
|
|
}
|
|
|
+
|
|
|
+ return rx_msg_num;
|
|
|
}
|
|
|
|
|
|
-void CAN1_IRQHandler(void)
|
|
|
+void CAN0_IRQHandler(void)
|
|
|
{
|
|
|
- uint8_t isr=0,errint=0;
|
|
|
- CanPort_t *pCanPort = pxCanPort[CAN_ID1];
|
|
|
- CANFD_TypeDef *CANx = NULL;
|
|
|
- CanMsg RxMessage = {0};
|
|
|
-
|
|
|
- // printf("CAN1_IRQHandler \r\n");
|
|
|
-
|
|
|
- if(pCanPort){
|
|
|
- CANx = pCanPort->pcan;
|
|
|
- isr = CANx->RTIF;
|
|
|
- errint= CANx->ERRINT;
|
|
|
- if(isr & CAN_IFR_TPIF){
|
|
|
- //printf("CAN1 TPIF\n");
|
|
|
- xQueueSendFromISR(pCanPort->tx_done, NULL, 0);
|
|
|
- }
|
|
|
- if(isr & CAN_IFR_TSIF){
|
|
|
- //printf("CAN1 TPIF\n");
|
|
|
- xQueueSendFromISR(pCanPort->Stb_tx_done, NULL, 0);
|
|
|
- }
|
|
|
- if(isr & CAN_IFR_ROIF){
|
|
|
- PERROR("CAN1 ROIF! \r\n");
|
|
|
- //can_reinit(pCanPort);
|
|
|
- }
|
|
|
- if(isr & CAN_IFR_EIF){
|
|
|
- PERROR("CAN1 EIF! \r\n");
|
|
|
- //can_reinit(pCanPort);
|
|
|
- }
|
|
|
-
|
|
|
- if(isr & (CAN_IFR_RF | CAN_IFR_RFIF | CAN_IFR_RAFIF)){
|
|
|
- CAN_RX(CANx, &RxMessage);
|
|
|
- if (!listLIST_IS_EMPTY(&pCanPort->rxFreeList)) {
|
|
|
- ListItem_t *item = listGET_HEAD_ENTRY(&pCanPort->rxFreeList);
|
|
|
- memcpy((void*)listGET_LIST_ITEM_VALUE(item), &RxMessage, sizeof(CanMsg));
|
|
|
- uxListRemove(item);
|
|
|
- vListInsertEnd(&pCanPort->rxRevList, item);
|
|
|
- xSemaphoreGiveFromISR(pCanPort->xRev, 0);
|
|
|
- } else {
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(CANx->CFG_STAT & 0x01){
|
|
|
- PERROR("BUSOFF!\n");
|
|
|
- }
|
|
|
-
|
|
|
- if(errint & CAN_EIFR_EWARN){ // 错误计数器值超过EWL时会产生该中断
|
|
|
- PERROR("CAN_EIFR_EWARN! TECNT:0x%x RECNT:0x%x \r\n",CANx->TECNT, CANx->RECNT);
|
|
|
- }
|
|
|
- if(errint & CAN_EIFR_EPASS){ // 错误被动模式激活,即错误计数 >127 此位为1
|
|
|
- PERROR("CAN_EIFR_EPASS! \r\n");
|
|
|
- }
|
|
|
- if(errint & CAN_EIFR_EPIF){ // 错误计数器向上或向下越过127都会产生该中断
|
|
|
- PERROR("CAN_EIFR_EPIF! \r\n");
|
|
|
- }
|
|
|
- if(errint & CAN_EIFR_ALIF){
|
|
|
- PERROR("CAN_EIFR_ALIF! \r\n");
|
|
|
- }
|
|
|
- if(errint & CAN_EIFR_BEIF){ // 总线错误
|
|
|
- PERROR("CAN_EIFR_BEIF! \r\n");
|
|
|
- }
|
|
|
+ CAN_IRQHandler(pxCanPort[CAN_ID0]);
|
|
|
+}
|
|
|
|
|
|
- CANx->RTIF = isr;
|
|
|
- CANx->ERRINT = errint;
|
|
|
- }
|
|
|
+void CAN1_IRQHandler(void)
|
|
|
+{
|
|
|
+ CAN_IRQHandler(pxCanPort[CAN_ID1]);
|
|
|
}
|
|
|
|
|
|
static void can_ptb_transmit_thread(void *param)
|
|
|
@@ -1011,6 +883,7 @@ static void can_ptb_transmit_thread(void *param)
|
|
|
CAN_PTB_Tran(cap->pcan, msgs);
|
|
|
xSemaphoreGive(cap->xTBSELMutex);
|
|
|
if (xQueueReceive(cap->tx_done, NULL, pdMS_TO_TICKS(1000)) != pdTRUE) {
|
|
|
+ PWARN("can tx timeout!\n");
|
|
|
/* transmit timeout, reset can */
|
|
|
can_reinit(cap);
|
|
|
}
|
|
|
@@ -1038,16 +911,14 @@ static void can_stb_transmit_thread(void *param)
|
|
|
vListInsertEnd(&cap->StbtxFreeList, item);
|
|
|
portEXIT_CRITICAL();
|
|
|
xQueueReset(cap->Stb_tx_done);
|
|
|
- if(cap->ttcan){
|
|
|
- CAN_TTCAN_Tran(cap->pcan, msgs);
|
|
|
- }else{
|
|
|
+ {
|
|
|
xSemaphoreTake(cap->xTBSELMutex, portMAX_DELAY);
|
|
|
stb_nfull = CAN_STB_FIFO_Tran(cap->pcan, msgs);
|
|
|
xSemaphoreGive(cap->xTBSELMutex);
|
|
|
if(stb_nfull){
|
|
|
|
|
|
}else if (xQueueReceive(cap->Stb_tx_done, NULL, pdMS_TO_TICKS(1000)) != pdTRUE) {
|
|
|
- printf("can tx timeout!\n");
|
|
|
+ PWARN("can tx timeout!\n");
|
|
|
/* transmit timeout, reset can */
|
|
|
can_reinit(cap);
|
|
|
}
|
|
|
@@ -1058,7 +929,6 @@ static void can_stb_transmit_thread(void *param)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
CanPort_t *xCanOpen(u32 id)
|
|
|
{
|
|
|
int i;
|
|
|
@@ -1149,7 +1019,7 @@ CanPort_t *xCanOpen(u32 id)
|
|
|
/* Create a task to transmit can msg */
|
|
|
if (xTaskCreate(can_ptb_transmit_thread, "can_ptb_trm", configMINIMAL_STACK_SIZE, cap,
|
|
|
(configMAX_PRIORITIES / 3 + 2) | portPRIVILEGE_BIT, &cap->xTxThread) != pdPASS) {
|
|
|
- printf("create can transmit task fail.\n");
|
|
|
+ PERROR("create can transmit task fail.\n");
|
|
|
vCanClose(cap);
|
|
|
return NULL;
|
|
|
}
|
|
|
@@ -1157,7 +1027,7 @@ CanPort_t *xCanOpen(u32 id)
|
|
|
/* Create a task to transmit can msg */
|
|
|
if (xTaskCreate(can_stb_transmit_thread, "can_stb_trm", configMINIMAL_STACK_SIZE, cap,
|
|
|
(configMAX_PRIORITIES / 3 + 2) | portPRIVILEGE_BIT, &cap->xStbTxThread) != pdPASS) {
|
|
|
- printf("create can transmit task fail.\n");
|
|
|
+ PERROR("create can transmit task fail.\n");
|
|
|
vCanClose(cap);
|
|
|
return NULL;
|
|
|
}
|
|
|
@@ -1203,23 +1073,18 @@ static void can_pad_cfg(CanPort_t *cap)
|
|
|
*@param:
|
|
|
* fd_baud: 在发送FD帧且BRS=1时数据段的波特率(仅在FD=1,BRS=1时有效).
|
|
|
* baud: 在BRS=0发送时为全帧的波特率, 在发送FD帧且BRS=1时为仲裁段波特率.
|
|
|
- *@note TTCAN 不支持
|
|
|
+ *@note
|
|
|
*/
|
|
|
-void vCanInit(CanPort_t *cap, CanTimInit_t *TimInit, CanMode_t mode, u8 ttcan)
|
|
|
+void vCanInit(CanPort_t *cap, CanTimInit_t *TimInit, CanMode_t mode)
|
|
|
{
|
|
|
CAN_InitTypeDef CAN_InitStructure;
|
|
|
|
|
|
- ttcan = 0; // TTCAN NO SUPPORT
|
|
|
-
|
|
|
- CAN_InitStructure.BitTiming = can_baud_param_tab[TimInit->Bps];
|
|
|
+ CAN_InitStructure.BitTiming = canfd_baud_param_tab[TimInit->Bps];
|
|
|
CAN_InitStructure.DataBitTiming = canfd_baud_param_tab[TimInit->DatBps];
|
|
|
CAN_InitStructure.tdc_en = TimInit->tdc_en;
|
|
|
CAN_InitStructure.sspoff = TimInit->sspoff;
|
|
|
CAN_InitStructure.FD_En = 1;
|
|
|
CAN_InitStructure.Mode = mode;
|
|
|
- CAN_InitStructure.ttcan = ttcan;
|
|
|
- CAN_InitStructure.t_presc = TimInit->t_presc;
|
|
|
- cap->ttcan = ttcan;
|
|
|
|
|
|
CanInitValue[cap->id] = CAN_InitStructure;
|
|
|
if (cap->id == CAN_ID0){
|
|
|
@@ -1310,8 +1175,20 @@ void vCanSetFilter(CanPort_t *cap, CAN_FilterInitTypeDef CAN_FilterInitStruc
|
|
|
CANx->ACF_EN_1 |= (1 << (CAN_FilterInitStruct.FILTERx - 8));
|
|
|
}
|
|
|
|
|
|
- CanFilterInitValue[cap->id] = CAN_FilterInitStruct;
|
|
|
- nCanFilterEnable[cap->id] = 1;
|
|
|
+ CanFilterInitValue[cap->id][CAN_FilterInitStruct.FILTERx] = CAN_FilterInitStruct;
|
|
|
+ if ((CAN_FilterInitStruct.IDE_M == STD_OR_EXT) || (CAN_FilterInitStruct.IDE_M == EXT_ONLY)) {
|
|
|
+ if (CAN_FilterInitStruct.IDMASK & 0x1FFFFFFF == 0x1FFFFFFF) {
|
|
|
+ nCanFilterEnable[cap->id][CAN_FilterInitStruct.FILTERx] = 0;
|
|
|
+ } else {
|
|
|
+ nCanFilterEnable[cap->id][CAN_FilterInitStruct.FILTERx] = 1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (CAN_FilterInitStruct.IDMASK & 0x7ff == 0x7ff) {
|
|
|
+ nCanFilterEnable[cap->id][CAN_FilterInitStruct.FILTERx] = 0;
|
|
|
+ } else {
|
|
|
+ nCanFilterEnable[cap->id][CAN_FilterInitStruct.FILTERx] = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
CAN_Init(cap->pcan, &(CanInitValue[cap->id]));
|
|
|
}
|
|
|
@@ -1327,12 +1204,7 @@ int iCanWrite(CanPort_t *cap, CanMsg* messages, int nmsgs, TickType_t xBlockTime
|
|
|
List_t *txFreeList = NULL;
|
|
|
List_t *txSendList = NULL;
|
|
|
|
|
|
- if(cap->ttcan){
|
|
|
- TxMutex = cap->xStbTxMutex;
|
|
|
- xSend = cap->xStbSend;
|
|
|
- txFreeList = &cap->StbtxFreeList;
|
|
|
- txSendList = &cap->StbtxSendList;
|
|
|
- }else{
|
|
|
+ {
|
|
|
switch(msgs->TxMode){
|
|
|
case XMIT_PTB_MODE:
|
|
|
TxMutex = cap->xTxMutex;
|
|
|
@@ -1341,7 +1213,7 @@ int iCanWrite(CanPort_t *cap, CanMsg* messages, int nmsgs, TickType_t xBlockTime
|
|
|
txSendList = &cap->txSendList;
|
|
|
break;
|
|
|
case XMIT_STB_FIFO:
|
|
|
- case XMIT_SEP_PRIO:
|
|
|
+ case XMIT_STB_PRIO:
|
|
|
TxMutex = cap->xStbTxMutex;
|
|
|
xSend = cap->xStbSend;
|
|
|
txFreeList = &cap->StbtxFreeList;
|
|
|
@@ -1366,11 +1238,13 @@ int iCanWrite(CanPort_t *cap, CanMsg* messages, int nmsgs, TickType_t xBlockTime
|
|
|
xSemaphoreGive(xSend);
|
|
|
} else {
|
|
|
portEXIT_CRITICAL();
|
|
|
- if (xTaskGetTickCount() - starttime > xBlockTime){
|
|
|
- printf("can write timeout!\n");
|
|
|
- break;
|
|
|
+ {
|
|
|
+ if (xTaskGetTickCount() - starttime > xBlockTime) {
|
|
|
+ PWARN("can write timeout!\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ vTaskDelay(1);
|
|
|
}
|
|
|
- vTaskDelay(1);
|
|
|
}
|
|
|
|
|
|
if (xBlockTime && xTaskGetTickCount() - starttime > xBlockTime)
|