MPC 5748 CANFD

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

MPC 5748 CANFD

164 Views
徐工2024
Contributor I

您好,我最近在测试MPC5748G的CANFD功能,能实现它的发送以及接收中断功能,但是目前遇到的问题是,我无法使用block块1/2来进行发送数据,只能使用block0才能发送数据,如下是我的代码:

void FlexCAN0_Init(void)
{
    uint32_t i = 0;
 
    /* enable the FlexCAN module, reset and freeze */
    CAN_0.MCR.R = (0
                    | CAN_MCR_FRZ  /* enabled to enter Freeze mode */
                    | CAN_MCR_HALT /* enter freeze mode if FRZ bit is set */
                    //| CAN_MCR_SOFTRST /* soft reset */
                    //| CAN_MCR_SRXDIS  /* self reception enabled */
                    | CAN_MCR_BCC  /* individual Rx masking and queue */
                    | 0x0000001F);
 
    /* double check that we are actually in freeze mode */
    while(0 == CAN_0.MCR.B.FRZACK) {};
    while(0 == CAN_0.MCR.B.NOTRDY) {};
 
    CAN_0.MCR.R = (0
                    | CAN_MCR_FRZ  /* enabled to enter Freeze mode */
                    | CAN_MCR_HALT /* enter freeze mode if FRZ bit is set */
                    /*| CAN_MCR_SRXDIS */ /* self reception enabled */
                    | CAN_MCR_BCC  /* individual Rx masking and queue */
                    | CAN_MCR_AEN  /* Safe Tx abort enable */
| CAN_MCR_FDEN /* CAN FD enabled */
                    | 0x0000001F); /* enable 32 MBs */
 
    //CAN_0.CBT.R = 0x802D29AD; // Nominal bit time: 40 MHz clksrc, 500K bps with 40 tq
                              // EPRESDIV = 1, EPROPSEG = 10, EPSEG1 = 13, EPREG2 = 13
    CAN_0.CBT.R = 0x80272A67;  // bitrate=500kbps, CPI clk=40 MHz; Prescaler= 2, PROPSEG=11, PSEG1=20, PSEG2=8, RJW=8, smp=80%
    CAN_0.FDCBT.R = 0x00111421;  // bitrateFD=2000kbps, CPI clk=40 MHz; fPrescaler= 2, fPROPSEG=5, fPSEG1=2, fPSEG2=2, fRJW=2, smp=80%
 
 
    //CAN_0.FDCBT.R = 0x00130862; // Data bit time: 40 MHz clksrc, 2Mbps with 10 tq
                                // FPRESDIV = 1, FPROPSEG = 2, FPSEG1 = 3, FPREG2 = 4
    //CAN_0.FDCBT.R = 0x00330425;
    CAN_0.FDCTRL.R = 0x8030000;  // bit rate switching enable, 64byte payload for region 0
//    CAN_0.FDCTRL.B.MBDSR1 = 3;    // TCD disabled
 
    /* clear MB are for first 32MBs */
    for(i=0;i<(32*4);i++)
    {
    CAN_0.RAMn[i].R = 0;
    }
 
    /* set mask registers - all ID bits must match */
    for(i=0;i<32;i++)
    {
        CAN_0.RXIMR[i].R = 0x1FFFFFFF;
    }
 
    CAN_0.CTRL2.R |= 0x1000; // set ISOCANFDEN bit 大端
    /*enable interrupt for MB3*/
    CAN_0.IMASK1.R = 0x00000004; //小端
    /* Finally clear the HALT flag in MCR to enable the FlexCAN
     * to synchronize with the CAN bus and allow
     * participation in communication. */
    CAN_0.MCR.B.HALT = 0;
 
    /* wait until FlexCAN ready */
    while(1 == CAN_0.MCR.B.FRZACK){};
    while(1 == CAN_0.MCR.B.NOTRDY){};
}
 
/*******************************************************************************
Function Name : GetMBAddr
Engineer      : Petr Stancik
Date          : Jun-22-2021
Parameters    : mb ... mb number used
Modifies      : NONE
Returns       : address of MB
Notes         : get address of selected MB depending on payload set for memory block
  memory block 0 is only checked
Issues        : NONE
*******************************************************************************/
uint32_t GetMBAddr(uint32_t mb)
{
//根据payload有效载荷大小来计算出每个MB的地址长度,因为这个版本的库没有封装MB寄存器
//检查的MBDSR0位的有效载荷大小,这个位描述的是block 0 的有效载荷,如果要知道其他 block 的 MB就需要修改与的位,以及下方RAMn的积地址(修改RAMn是个人理解,还未实践过)
uint8_t payload_size = 1UL << (((CAN_0.FDCTRL.R & 0x30000U) >> 16U) + 3U); // R & 0x30000U get payload size for memory block 0
 
//根据上面的小算法按照有效载荷大小来计算MB地址长度,根据地址长度在基地址上进行偏移得到想要的MB寄存器的地址
//CAN_0.RAMn是每个元素占用4字节,384/96 = 4 ,定义的这个数组空间实际表示的是MB一共占用的内存大小
return ((uint32_t)&CAN_0.RAMn[0].R + (8+payload_size)*mb);
 
/* 如果要知道其他 block 下的 MB 地址,则需要根据 */
 
}
 
/*******************************************************************************
Function Name : TransmitMsgFD
Engineer      : Petr Stancik
Date          : Jun-22-2021
Parameters    : mb ... mb number used
ext ... 0-standard ID, 1-extended ID
                ID ... ID to be sent
                length ... number of bytes to be sent
Modifies      : NONE
Returns       : NONE
Notes         : Transmit message once using selected MB
Issues        : NONE
*******************************************************************************/
void TransmitMsgFD(uint32_t mb, uint8_t ext, uint32_t ID, uint8_t length)
{
/* Assumption:  Message buffer CODE is INACTIVE */
  uint8_t i,dlc,z=0;
  uint32_t *pTxMB = GetMBAddr(mb);
  uint32_t txID = (ext==0) ? ID<<18 : ID;
 
  /*calculate dlc value from no. bytes*/
  if(length < 0x09)
  {
      dlc = length;
  }else if(length < 0x0D){
      dlc = 0x9;
  }else if(length < 0x11){
      dlc = 0xA;
  }else if(length < 0x15){
      dlc = 0xB;
  }else if(length < 0x19){
      dlc = 0xC;
  }else if(length < 0x21){
      dlc = 0xD;
  }else if(length < 0x31){
      dlc = 0xE;
  }else{
      dlc = 0xF;
  }
 
 
  *(pTxMB + 1) = txID; // write ID
 
  for (i=0; i<length/4; i++,z+=4) {
    *(pTxMB + 2 + i) =  z<<24 | (z+1)<<16 | (z+2)<< 8 | z+3;      /* Data to be transmitted */
  }
 
  *pTxMB = (0 // Tx Buffer 0 T0 word
           | 1<<31 // extended Data Length
   | 1<<30 // bit rate switch
           | 0xC<<24 // code = 0xC, TX once
           | 1<<22 // SRR = 1
           | ext<<21 // IDE
           | 0<<20 // RTR = 0
           | dlc<<16);  // DLC
 
  while (!(CAN_0.IFLAG1.R & 1<<mb)) {};  /* Wait for CAN 0 MB 0 flag */
  CAN_0.IFLAG1.R = 1<<mb; // clear MB flag
}

 

我个人理解的是,我将block0配置payload为64字节,因此只能使用0~6的MB,为了能使用block1,我将设置CAN_0.FDCTRL.R = 0x80180000; 是block1也为64字节有效载荷,除了更改这一部分还更改的部分有GetMBAddr中payload_size = 1UL << (((CAN_0.FDCTRL.R & 0x180000U) >> 16U) + 3U);使其能获得MB7~13的地址,但是我这么修改我无法发送出数据,程序会一直卡在while (!(CAN_0.IFLAG1.R & 1<<mb)) {};不知道是什么原因,我认为问题是出在GetMBAddr函数获取MB地址这一部分,对于这一部分我理解的不是很透彻,不知道要如何进行修改才能获取block1下MB的地址,使block1也能发送canfd数据

0 Kudos
Reply
0 Replies