AnsweredAssumed Answered

How to config CAN RXFIFO DMA on MPC5748G?

Question asked by liu yang on Mar 28, 2019
Latest reply on Mar 30, 2019 by liu yang

Hello 

  I try to  config CAN RXFIFO DMA,  but it only work one times! The follow is my Init code.Thank very much!

 

Best wish

 

void DMA_Init(void)
{
DMAMUX_0.CHCFG[0].R = 0x80 | 5; //Route FlexCAN1 to DMA CHANNEL 0

EDMA.TCD[DMA_CHANNEL].SADDR.R = CAN0_BASE_ADDRESS + 0x80; /* Load Address of Source data */
EDMA.TCD[DMA_CHANNEL].ATTR.B.SSIZE = 2; /* Read 2**0 = 1 byte per transfer */
EDMA.TCD[DMA_CHANNEL].ATTR.B.SMOD = 0; /* Source Modulo feature not used */
EDMA.TCD[DMA_CHANNEL].SOFF.R = 4; /* After tranfer, add 0 to src addr */
EDMA.TCD[DMA_CHANNEL].SLAST.R = -16; /* No address Adjustment after major loops */

EDMA.TCD[DMA_CHANNEL].DADDR.R = (unsigned int)&RxDATA[0]; /* Destination Address */
EDMA.TCD[DMA_CHANNEL].ATTR.B.DSIZE = 2; /* Write 2**0 = 1 byte per transfer */
EDMA.TCD[DMA_CHANNEL].ATTR.B.DMOD = 0; /* Destination modulo feature not used */
EDMA.TCD[DMA_CHANNEL].DOFF.R = 4; /* Increment destination addr by 1 */
EDMA.TCD[DMA_CHANNEL].DLASTSGA.R = -16; /* No addr adjustment after major loop */

EDMA.TCD[DMA_CHANNEL].CSR.B.DREQ = 1; /* Disable Request */
EDMA.TCD[DMA_CHANNEL].NBYTES.MLNO.B.NBYTES = 16; /* NBYTES - Transfer 1 byte per minor loop */
/* TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled) */
EDMA.TCD[DMA_CHANNEL].CITER.ELINKNO.B.ELINK = 0; /* Enable channel-to-channel linking on minor-loop complete */
EDMA.TCD[DMA_CHANNEL].CITER.ELINKNO.B.CITER = 1; /* Current Major Iteration Count */
/* TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */
EDMA.TCD[DMA_CHANNEL].BITER.ELINKNO.B.ELINK = 0; /* Enables channel-to-channel linking on minor loop complete */
EDMA.TCD[DMA_CHANNEL].BITER.ELINKNO.B.BITER = 1; /* Starting Major Iteration Count */
EDMA.TCD[DMA_CHANNEL].CSR.B.MAJORELINK = 0; /* Enable channel-to-channel linking on major loop complete */
EDMA.TCD[DMA_CHANNEL].CSR.B.ESG = 0; /* Enable Scatter/Gather Processing */
EDMA.TCD[DMA_CHANNEL].CSR.B.BWC = 0; /* Bandwidth Control */
EDMA.TCD[DMA_CHANNEL].CSR.B.INTHALF = 0; /* Disable an interrupt when major counter is half complete. */
EDMA.TCD[DMA_CHANNEL].CSR.B.INTMAJOR = 1; /* Disable an interrupt when major iteration count completes */
EDMA.TCD[DMA_CHANNEL].CSR.B.MAJORLINKCH = 0; /* Link Channel Number */
EDMA.TCD[DMA_CHANNEL].CSR.B.START = 0; /* Channel Start */
EDMA.TCD[DMA_CHANNEL].CSR.B.DONE = 0; /* Channel Done */
EDMA.TCD[DMA_CHANNEL].CSR.B.ACTIVE = 0; /* Channel Active */
INTC.PSR[53].B.PRC_SELN = 0x8; /* IRQ sent to Core 0 */
INTC.PSR[53].B.PRIN =10; /* IRQ priority = 10 (15 = highest) */

EDMA.SERQ.R = 0; /* Enable channel 0 */
// EDMA.SERQ.R = 16; /* Enable channel 0 */
}

 


void initCAN_0_rx(void) { /* General init. MB IDs: MB4 ID_STD=0x555 */
uint16_t i;

CAN_0.MCR.B.MDIS = 1; /* Disable module before selecting clock source*/
CAN_0.CTRL1.B.CLKSRC=0; /* Clock Source = oscillator clock (40 MHz) */
CAN_0.MCR.B.MDIS = 0; /* Enable module for config. (Sets FRZ, HALT)*/
while (!CAN_0.MCR.B.FRZACK) {}/* Wait for freeze acknowledge to set */
/* Good practice: wait for FRZACK on freeze mode entry/exit */
CAN_0.CTRL1.R = 0x04DB0086; /* CAN bus: 40 MHz clksrc, 500K bps with 16 tq */
/* PRESDIV+1 = Fclksrc/Ftq = 40 MHz/8MHz = 5 */
/* so PRESDIV = 4 */
/* PSEG2 = Phase_Seg2 - 1 = 4 - 1 = 3 */
/* PSEG1 = PSEG2 = 3 */
/* PROPSEG= Prop_Seg - 1 = 7 - 1 = 6 */
/* RJW = Resync Jump Width - 1 = 4 = 1 */
/* SMP = 1: use 3 bits per CAN sample */
/* CLKSRC=0 (unchanged): Fcanclk= Fxtal= 40 MHz*/
for (i=0; i<64; i++) { /* MPC574xG has 96 buffers after MPC5748G rev 0*/
CAN_0.MB[i].CS.B.CODE = 0; /* Inactivate all message buffers */
}
// CAN_0.MB[4].CS.B.IDE = 0; /* MB 4 will look for a standard ID */
// CAN_0.MB[4].ID.B.ID_STD = 0x555; /* MB 4 will look for ID = 0x555 */
// CAN_0.MB[4].CS.B.CODE = 4; /* MB 4 set to RX EMPTY */


CAN_0.RXMGMASK.R = 0x1FFFFFFF;/* Global acceptance mask */

SIUL2.MSCR[16].B.SSS = 1; /* Pad PB0: Source signal is CAN0_TX */
SIUL2.MSCR[16].B.OBE = 1; /* Pad PB0: Output Buffer Enable */
SIUL2.MSCR[16].B.SRC = 3; /* Pad PB0: Maximum slew rate */
SIUL2.MSCR[17].B.IBE = 1; /* Pad PB1: Enable pad for input - CAN0_RX */
SIUL2.IMCR[188].B.SSS = 2; /* CAN0_RX: connected to pad PB1 */

/* If DMA is used for receiving, it is necessary to enable RX FIFO */
/* RX FIFO structure is placed at address CAN_BASE_ADDRESS + 0x80 */
/* First "ID filter table element 0" is placed at CAN_BASE_ADDRESS + 0xE0 */

CAN_0.CTRL2.B.RFFN = 0x0; /* Message buffers 0-7 are occupied by RX FIFO and ID filter table */
/* There are 8 ID filter table elements */

CAN_0.MCR.B.IDAM = 0x0; /* One full ID (standard and extended) per ID Filter Table element */

/* Initialize ID filter table elements 0-7 to receive messages with standard ID 0x555 (RTR and IDE = 0) */
// for(i = 0xE0; i<0xFF ;i=i+4)
i = 0xE0;
*(unsigned int*)(CAN0_BASE_ADDRESS + i) = 0x555<<19;
i = 0xE0 + 4;
*(unsigned int*)(CAN0_BASE_ADDRESS + i) = 0x666<<19;

/* Enable DMA, enable RX FIFO, negate FlexCAN 0 halt state for 64 MBs */
CAN_0.MCR.R = 0x2000803F;
while (CAN_0.MCR.B.FRZACK & CAN_0.MCR.B.NOTRDY) {} /* Wait to clear */
/* Good practice: wait for FRZACK on freeze mode entry/exit */
}

 

void AIPS_Init(void)
{
/* Enable DMA access on Peripheral Bridges*/
AIPS_A.MPRA.B.MTR4 = 1;
AIPS_A.MPRA.B.MTW4 = 1;
AIPS_A.MPRA.B.MPL4 = 1;

AIPS_B.MPRA.B.MTR4 = 1;
AIPS_B.MPRA.B.MTW4 = 1;
AIPS_B.MPRA.B.MPL4 = 1;
}//AIPS_Init

 

void DMA_0_ISR(void)
{

   EDMA.INT.R = 0x1; /* Clear interrupt flag for DMA channel 0 */

}

 

int main(void)
{
    unsigned char Input;
     int counter = 0;

     xcptn_xmpl (); /* Configures and Enables Interrupts */

    peri_clock_gating(); /* Configures gating/enabling peripheral clocks for modes*/
   /* Configuration occurs after mode transition */
    system160mhz(); /* sysclk=160MHz, dividers configured, mode transition*/

   hw_init();

 

    AIPS_Init();

   /* Configure DMA channel 16 to receive one frame from CAN1 */
    DMA_Init();


    initCAN_0_rx(); /* Initialize FLEXCAN 0 & one of its buffers for receive*/

 

    while(1) {
     }
     return 0;
}

Outcomes