s12g128 MSCAN filter dose not work properly

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

s12g128 MSCAN filter dose not work properly

2,567 Views
gaoqiang
Contributor III

Dear:

Thanks for your attention!

I have set s12g128 MSCAN in filter mode , there are two can id should be received,  id0 = 0x280, id1 = 0x1A0 ,

CAN filter configration as four 16bit mode , filter0 receive 0x280, filter1 receive 0x1A0.

During the test, it was found that only filter0 can receive normally, it could receive 0x280's message, but filter1 does not work. It can be determined that 0x1A0 information on the CAN bus is normaly.

the s12g128 MSCAN configration code as follows:

/* ---------------------------------------------------------------------- */

void mscan_init(uchar BRP_value)
{
    if (CANCTL0_INITRQ == 0// 查询是否进入初始化状态
        CANCTL0_INITRQ = 1;  // 进入初始化状态

    while (CANCTL1_INITAK == 0)
        ; // 等待初始化响应

    CANBTR0_SJW = 0;               // 同步跳跃脉宽设置 1Tq
    CANBTR0_BRP = (BRP_value - 1); // 预分频数设置为BRP_value
    CANBTR1_SAMP = 0;              // 采样数为1
    CANBTR1_TSEG_20 = 2;
    CANBTR1_TSEG_10 = 11// 相位缓冲段SEG1、SEG2长度设置 12,3个Tq
    CANIDAC = 0x10;       /* four 16-bit filters */
    //CANIDAC = 0x00;         /* two 32-bit filters */

    /* filters0 ID = 0x280 Standard Identifier */
    CANIDAR0 = 0x00 | (uint8_t)(0x280 >> 3); //bit 10 ~ bit3
    CANIDMR0 = 0x00;
    CANIDAR1 = 0x00 | (uint8_t)(0x280 << 5); //bit 2 ~ bit0
    CANIDMR1 = 0x07;

    /* filters1 ID = 0x1A0 Standard Identifier */
    CANIDAR2 = 0x00 | (uint8_t)(0x1A0 >> 3); //bit 10 ~ bit3
    CANIDMR2 = 0x00;
    CANIDAR3 = 0x00 | (uint8_t)(0x1A0 << 5); //bit 2 ~ bit0
    CANIDMR3 = 0x07;

    /* filters2 ID = 0x000 Standard Identifier */
    CANIDAR4 = 0x00;
    CANIDMR4 = 0x00;
    CANIDAR5 = 0x00;
    CANIDMR5 = 0x07;

    /* filters3 ID = 0x000 Standard Identifier */
    CANIDAR6 = 0x00;
    CANIDMR6 = 0x00;
    CANIDAR7 = 0x00;
    CANIDMR7 = 0x07;

    CANCTL1 = 0xC0//CAN工作模式的设置 选择24M总线时钟
    //CANCTL1 = 0x80;//使能MSCAN,选择外部晶振为MSCAN时钟源
    //配置工作模式
    CANCTL1_LISTEN = 0//侦听模式禁止
    //设置中断方式
    CANTIER = 0x00//禁止发送中断
    CANRIER = 0x00//禁止接收中断
    CANCTL0 = 0x00//返回一般模式运行

    while (CANCTL1_INITAK)
        ; //等待关闭初始化响应

    while (CANCTL0_SYNCH == 0)
        ; //等待CAN同步(连到总线时需要判断同步)

    CANTFLG_TXE = CANTFLG_TXE_MASK; //清空消息发送缓冲器
    CANRFLG_RXF = 1;                //清空消息接收缓冲器
    CANRIER_RXFIE = 1;              //使能接收消息中断
}
/* and the can receive interrupt code is follows: */
//CAN接收中断函数
interrupt void CAN_Rx_ISR(void)
{
    if (CANRFLG_RXF == 1)
    {
        mscan_receive(canRxMsg);
    }

    CANRFLG_RXF = 1;    /* Clear the interrupt flag */
}
/**CAN接收函数
 * error: return 1,2,3
 * success: return 0 */
static unsigned char mscan_receive(mscan_msg_t msg)
{
    unsigned char i = 0;
    unsigned char temp = 0;

    /*****************************************************************/
    /* Standard formate */
    if (0 == CANRXIDR1_IDE)
    {
        msg->id = ((unsigned int)CANRXIDR0 << 3| (CANRXIDR1 >> 5);
        msg->ide = 0;

        if (0 == CANRXIDR1_SRR) /* 判断是数据帧 or 远程帧 */
        {
            msg->rtr = 0;
        }
        else
        {
            msg->rtr = 1;
        }
    }
    /*****************************************************************/
    /* Extended formate */
    else
    {
        temp = CANRXIDR0;
        msg->id = (((unsigned long)temp) << 21& 0x1FE00000;
        temp = CANRXIDR1;
        (uchar) temp = (((temp & 0xE0>> 2+ (temp & 0x07));
        msg->id = msg->id + ((((unsigned long)temp) << 15& 0x1F8000);
        //temp = 0;
        temp = CANRXIDR2;
        msg->id = msg->id + ((((unsigned long)temp) << 7& 0x7F80);
        temp = CANRXIDR3;
        msg->id = msg->id + ((unsigned long)(temp >> 1& 0x7F);
        msg->ide = 1;

        if (0 == CANRXIDR3_RTR) /* 判断是数据帧 or 远程帧 */
        {
            msg->rtr = 0;
        }
        else
        {
            msg->rtr = 1;
        }
    }

    if (0 == msg->rtr/* 如果是数据帧,则接收数据 */
    {
        /* Receive Data and Datalength */
        msg->len = CANRXDLR;

        if (msg->len > 8)
        {
            msg->len = 8;
        }

        for (i = 0; i < msg->len; i++)
        {
            msg->data[i] = *(&(CANRXDSR0) + i);
        }
    }
    else
    {
        msg->len = 0;
    }

    msg->sta = 1;
}
Thank you for your answer!
Tags (2)
0 Kudos
Reply
9 Replies

2,256 Views
RadekS
NXP Employee
NXP Employee

Hi Gao,

I cannot see any obvious issues for now.

Are you sure that these IDs are for standard type data frames?
Your filter configuration masks all messages with extended identifiers and also all remote frames.

While your receive function works with remote frames and extended format IDs by default. 

For receiving also remote frames use CANIDMRx = 0x17;

Best regards

Radek

0 Kudos
Reply

2,256 Views
gaoqiang
Contributor III

Hi Radek:

use USB-CAN tools receive the CAN BUS data , I can read the 0x280 & 0x1A0 CAN IDs data as follows pictures, thanks!

Best regards

GAO

2020-02-13_164218.jpg

2020-02-13_164311.jpg

0 Kudos
Reply

2,256 Views
RadekS
NXP Employee
NXP Employee

Hi Gao,

thank you for more details.

Could you please check CANRFLG_OVRIF flag? It seems that Overrun interrupt isn't enabled.

Could you please also periodically check CANIDAC_IDHITx bits for excluding any issue on the software side?
Please check also CANIDARx and CANIDMRx registers for ensuring that correct values are presented.

CANIDAR0=0x50

CANIDMR0=0x00

CANIDAR1=0x00

CANIDMR1=0x07

CANIDAR2=0x34

CANIDMR2=0x00

CANIDAR3=0x00

CANIDMR3=0x07

BTW: how you detect that message with 0x280 didn't arrive? I guess that you probably periodically test canRxMsg global variable. Cannot be a source of issue any timing synchronization?

I would like to propose some debug GPIO pins (LEDs) toggling directly in mscan_receive() function. 

Best regards

Radek

0 Kudos
Reply

2,256 Views
gaoqiang
Contributor III

Hi Radek:

 Thanks for your attention!

 When received can messages, I use serial to trans them to PC, only can receive the filter0 IDs.

Tomorrow I will test according to your suggestions. The link below is the source code. Please help me check it.

Sorry, I don’t know how to upload the attachment, so I will provide it to you in the form of shared network disk.

net disk link: https://pan.baidu.com/s/1l3qu1t1NtUz23nw9K9YnfQ
Extraction code: 8wci

Thank you very much!

Best regards

GAO

0 Kudos
Reply

2,256 Views
RadekS
NXP Employee
NXP Employee

Hi Gao,
Unfortunately, I was not able to found the right option of how to download it without registration or specific application. Probably just problem with web page translation.

If you want to upload attachment here, please click on Use advanced editor link at the top right corner of your reply window.

Use advanced editor.png
After that, you will see the attachment upload option directly under your reply.

Attach.png

Best regards

Radek

0 Kudos
Reply

2,256 Views
gaoqiang
Contributor III

Hi Radek,

In today ’s test, in the MSCAN initialization mode, set CANIDAC_IDAM = 1, or set CANIDAC = 0x10, that is, four 16-bit filter modes. After the program runs, it can only receive the IDs of filter0 and filter2, and read the CANIDAC The value is still 0, that is, the value of IDAM has not been written. MSCAN also works in two 32-bit modes, so it can only receive the IDs of filter0 and filter2. After searching online, I found a netizen Encountered the same problem, just need to set the CANCTL1 = 0xC0 register in advance, and that's it. The modified code is as follows:

/* -------------------------------------------------------------------------------------- */

void mscan_init_mask(uchar BRP_value)
{

    if (CANCTL0_INITRQ == 0// 查询是否进入初始化状态
        CANCTL0_INITRQ = 1;  // 进入初始化状态

    while (CANCTL1_INITAK == 0)
        ; // 等待初始化响应
      
    /* this register must be set at first */
    CANCTL1 = 0xC0; //CAN工作模式的设置 选择24M总线时钟

    CANBTR0_SJW = 0;               // 同步跳跃脉宽设置 1Tq
    CANBTR0_BRP = (BRP_value - 1); // 预分频数设置为BRP_value
    CANBTR1_SAMP = 0;              // 采样数为1
    CANBTR1_TSEG_20 = 2;
    CANBTR1_TSEG_10 = 11// 相位缓冲段SEG1、SEG2长度设置 12,3个Tq

    CANIDAC = 0x10;       /* four 16-bit filters */
    //CANIDAC = 0;         /* two 32-bit filters */

    /* filters0 ID = 0x280 Standard Identifier */
    CANIDAR0 = (uint8_t)(0x280 >> 3); //bit 10 ~ bit3
    CANIDMR0 = 0x00;
    CANIDAR1 = (uint8_t)(0x280 << 5); //bit 2 ~ bit0
    CANIDMR1 = 0x07;

    /* filters1 ID = 0x180 Standard Identifier */
    CANIDAR2 = (uint8_t)(0x180 >> 3); //bit 10 ~ bit3
    CANIDMR2 = 0x00;
    CANIDAR3 = (uint8_t)(0x180 << 5); //bit 2 ~ bit0
    CANIDMR3 = 0x07;

    /* filters2 ID = 0x1A0 Standard Identifier */
    CANIDAR4 = (uint8_t)(0x1A0 >> 3); //bit 10 ~ bit3
    CANIDMR4 = 0x00;
    CANIDAR5 = (uint8_t)(0x1A0 << 5); //bit 2 ~ bit0
    CANIDMR5 = 0x07;

    /* filters3 ID = 0x330 Standard Identifier */
    CANIDAR6 = (uint8_t)(0x330 >> 3); //bit 10 ~ bit3
    CANIDMR6 = 0x00;
    CANIDAR7 = (uint8_t)(0x330 << 5); //bit 2 ~ bit0
    CANIDMR7 = 0x07;

    //设置中断方式
    CANTIER = 0x00//禁止发送中断
    CANRIER = 0x00//禁止接收中断
    CANCTL0 = 0x00//返回一般模式运行

    while (CANCTL1_INITAK)
        ; //等待关闭初始化响应

    while (CANCTL0_SYNCH == 0)
        ; //等待CAN同步(连到总线时需要判断同步)

    CANTFLG_TXE = CANTFLG_TXE_MASK; //清空消息发送缓冲器
    CANRFLG_RXF = 1;                //清空消息接收缓冲器
    CANRIER_RXFIE = 1;              //使能接收消息中断
}
/* ------------------------------------------------------- */
Thank you very much!

Best regards

GAO
0 Kudos
Reply

2,256 Views
RadekS
NXP Employee
NXP Employee

Hi Gao,

I am glad that it works now and I am sorry that I didn't found it before.

Thank you for sharing the solution.

Best regards

Radek

0 Kudos
Reply

2,256 Views
gaoqiang
Contributor III

Hi Radek,

Sharing is right, and some of your suggestions gave me a better idea in debugging, thank you very much!

Best regards

GAO

0 Kudos
Reply

2,256 Views
gaoqiang
Contributor III

Hi Radek:

  Thanks for your replay!

  The 0x280 and 0x1A0 are standard can data frame, not remote ,not extended . I test them on the BJ40 car can bus , so I confirm their correctness,  and today I modify the filter 0 receive 0x1A0, filter 1 receive 0x280, then can only receive 0x1A0 IDs, Really confused ,:( .

thanks for your attention!

Best regards

GAO

0 Kudos
Reply