How to get LIN demo using DMA for MPC55xx/MPC56xx

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

How to get LIN demo using DMA for MPC55xx/MPC56xx

2,010 Views
plabgh
Contributor I

Hi ,

I am learning the MPC5634M Microcontroller Reference Manual.

I have tried the following example. It contains communication on LIN bus between two MPC5604B EVBs.

Example MPC5604B LINFlex LIN Master-Slave communication demo

But how to get LIN demo fully contains Tx and Rx functions using DMA for MPC55xx/MPC56xx ?

And, I have another question about how to write LIN transmit register (SCI_LTR).

26.4.2.6LIN transmit register (SCI_LTR) in MPC563XMRM.pdf, described as follows:

       0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15

     |-------|-----------------------|-------------------------------|

     |Parity |           ID          |               LEN             |

     |-------|-----------------------|-------------------------------|

Reset| 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 |

      16   17  18  19  20  21  22  23  24  25  26  27  28  29  30  31

     |---|---|---|---|---------------|-------------------------------|

     |CSM|CSE|CRC|TD |       TO      |               DATA            |

     |---|---|---|---|---------------|-------------------------------|

Reset| 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 |

26.5.6.3.1 Application controlled LIN TX frame generation in MPC563XMRM.pdf, described as follows:

The first byte written to the SCI_LTR contains the Identifier and Identifier Parity fields. The second byte written defines the number of data bytes to be transmitted. The third write access defines the CRC and checksum generation. The TD bit has to set to 1 to invoke the TX frame generation. The TO field bits must be set to 0.

For example, I want to set :

ID = 0x35;     LEN = 8;     CSM = 1;     CSE = 1;     TD = 1;

all other fields of register SCI_LTR are 0.

Here we don't consider the TXRDY flag in the SR register (SCI_SR).

I want to know how to write the LIN transmit register (SCI_LTR) ???

First method:

ESCI_A.LTR.R = ((0x00000035<<24) | (0x00000008<<16) | (0x000000D0<<8));

Or, second method:

ESCI_A.LTR.R = 0x35;   //1st byte Write

ESCI_A.LTR.R = 0x05;   //2st byte Write

ESCI_A.LTR.R = 0xD0;  //3st byte Write

I want to know what kind of method is correct for writing LIN transmit register (SCI_LTR).

tks!!!

Tags (3)
0 Kudos
9 Replies

975 Views
plabgh
Contributor I

It has been five days since the problem is put forward, and any engineer know how to solve my problem about writing SCI_LTR and Reading SCI_LRR register ?

thank you !

0 Kudos

975 Views
PetrS
NXP TechSupport
NXP TechSupport

This is a Master TX code I used and data is sent properly ...

/* LEN: the number of data bytes to be transmitted */

/* TxData: pointing to LIN Tx frame data bytes, not frame header bytes */

void LinTxFrame(unsigned char  ID,   unsigned char  LEN, unsigned char  *TxData)

{

    /* Assuming heap is defined in the linker file */

    uint8_t *DMATxFrame = (uint8_t*)malloc(LEN+3);

    /* Write LIN TX frame header and control information */

    DMATxFrame[0] = ID;

    DMATxFrame[1] = LEN;

    DMATxFrame[2] = 0xD0;     /* For LIN TX frame, TD must be set to 1 */

    memcpy(&DMATxFrame[3], TxData, LEN);

    #define DMA_CH 18 // DMA channel to be assigned

    EDMA.TCD[DMA_CH].SADDR = (vuint32_t)&DMATxFrame[0];

    EDMA.TCD[DMA_CH].SSIZE = 0;

    EDMA.TCD[DMA_CH].SOFF = 1;                           

    EDMA.TCD[DMA_CH].SLAST = -(LEN + 3);

    EDMA.TCD[DMA_CH].SMOD = 0;                            

    EDMA.TCD[DMA_CH].DADDR = ((vuint32_t)&ESCI_A.LTR.R);

    EDMA.TCD[DMA_CH].DSIZE = 0; 

    EDMA.TCD[DMA_CH].DOFF = 0;

    EDMA.TCD[DMA_CH].DLAST_SGA = 0;

    EDMA.TCD[DMA_CH].DMOD = 0;

    EDMA.TCD[DMA_CH].NBYTES = 1;         

    EDMA.TCD[DMA_CH].BITER = LEN + 3;             

    EDMA.TCD[DMA_CH].CITER = LEN + 3;             

    EDMA.TCD[DMA_CH].CITERE_LINK = 0;

    EDMA.TCD[DMA_CH].D_REQ = 1;                                 

    EDMA.TCD[DMA_CH].INT_HALF = 0;                              

    EDMA.TCD[DMA_CH].INT_MAJ = 0;

    EDMA.TCD[DMA_CH].CITERE_LINK = 0;                 

    EDMA.TCD[DMA_CH].BITERE_LINK = 0;

    EDMA.TCD[DMA_CH].MAJORLINKCH = 0;

    EDMA.TCD[DMA_CH].E_SG = 0;

    EDMA.TCD[DMA_CH].BWC = 0;

    EDMA.TCD[DMA_CH].START = 0;

    EDMA.TCD[DMA_CH].DONE = 0;

    EDMA.TCD[DMA_CH].ACTIVE = 0;

    EDMA.SERQR.R = DMA_CH;      /* Enable EDMA channel */

}

Regards,

Petr

0 Kudos

975 Views
plabgh
Contributor I

I originally try to use "malloc" function to alloc memery, but I don't.

Because it will lead to memory leaks if you don't free the memery allocated.

I intend to call the LIN Tx function every 100ms, so it will allocate LEN+3 bytes memery everytime.

And then the heap space will soon run out.

I use SCI Tx and Rx function using dma as an example to verify the function of SCI driver demo after using "malloc" and "free".

I try to free the memery allocated at the end of the SCI Tx funciton everytime.

But I find  there exist unreadable codes in SCI Tx bytes data received.

And, I have another question about how to read LIN receive register (SCI_LRR).

26.4.2.7 LIN receive register (SCI_LRR) in MPC563XMRM.pdf, described as follows:

       0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15

     |-------------------------------|-------------------------------|

     |                               D                               |

     |---------------|---------------|---------------|---------------|

Reset| 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 |

      16   17  18  19  20  21  22  23  24  25  26  27  28  29  30  31

     |-------------------------------|-------------------------------|

     |                               D                               |

     |---------------|---------------|---------------|---------------|

Reset| 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 |

I need how to retrieve the received data by subsequent read access from SCI_LRR ?

First method:

unsigned char LinRxData = 0;

LinRxData = (unsigned char)ESCI_A.LRR.R;

Or, second method:

unsigned char LinRxData = 0;

LinRxData = (unsigned char)(ESCI_A.LRR.R >> 24);

If there are 8 bytes data (exclude frame header) in LIN Tx frame, I want to konw how many times I need to read access from SCI_LRR register ?

two times ? or, eight times ?

SCI_LRR register provides how many bytes data of received LIN RX frames everytime ?

4 bytes ? or, just 1 byte ?

tks.

0 Kudos

975 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

The LRR register is read in a similar way the LTR is written. So use

unsigned char LinRxData = 0;

LinRxData = (unsigned char)(ESCI_A.LRR.R >> 24);

Or create a byte pointer or modify the header file.

The LRR register is read each time the single byte is received. So after the  RXRDY flag is set the application reads the LRR and clears the  RXRDY flag. If eight bytes is going to be received, the LRR will be read eight times.

BR,

Petr

0 Kudos

975 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

I wrote above how to access the LTR register. It does not work for you?

It is true that in the MPC5634M RM the register description is not so clear so it can be hard to imagine how to write to it.

You can look for example to the MPC5644A RM (http://cache.freescale.com/files/32bit/doc/ref_manual/MPC5644ARM.pdf), there is little bit better LTR register definition. The module is the same.

Your eSCI/DMA code looks quite normal, some little mistakes. So it can work. However in your TX function if you want to use variable-length array the memory alloc have to be used instead of the definition you have.

Anyway on the TRK board the testing will be hard as the LIN transceiver is part of the SBC chip so it has to be enabled.

Also as the eSCI offers just Master node functionality, you can easily test the Master TX function, but you cannot check the Master RX one as you need a Slave on the bus to send a data.

The LIN transceiver can be omitted and Master TX function can be tested if you connect RXDA and TXDA pins together. Both should be disconnected from transceiver.

BR,

Petr

0 Kudos

975 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

What I know there is no LIN example using the DMA available for MPC55xx/MPC56xx.

I can try to create some but you should specify for which device. The MPC560xB contains a LINFlex module while the MPC5634M the eSCI module. The LINFlex supports both the Master and Slave nodes but the eSCI just a Master node functionality.

For your question about SCI_LTR; you should write bytes separately into the most upper byte of the LTR register. So for example

ESCI_A.LTR.R = 0x35 << 24;   //1st byte Write

ESCI_A.LTR.R = 0x05 << 24;   //2st byte Write

ESCI_A.LTR.R = 0xD0 << 24;  //3st byte Write

Or use byte pointer then

uint8_t *p = (uint8_t *)&ESCI_A.LTR.R;

*p = 0x35;

*p = 0x05;

*p = 0xD0;

Or you can modify the header file to have a byte access to LTR.

BR,

Petr

0 Kudos

975 Views
plabgh
Contributor I

Hi,

I don't have an oscilloscope or LIN tool, so I can't verify the Tx and Rx function of LIN example using DMA.

Could you help me to check the following code logic, just the logic, tks.

void Lin_Init(unsigned short  BaudRate)

{

  SIU.PCR[89].B.PA        = 1;                  /* Configure pad: Tx and Rx */

  SIU.PCR[90].B.PA        = 1;

  ESCI_A.CR2.B.FBR     = 1;                  /* Fast Bit error detection performed */

  ESCI_A.CR2.B.BSTP   = 1;                  /* select transmission DMA stop on bit error detection */

  ESCI_A.CR2.B.BRK13 = 1;                  /* select break character length of 13 bit as required by LIN 2.0 */

  ESCI_A.CR2.B.SBSTP = 1;                 /* select transmission stop on bit error detection */

  ESCI_A.CR1.B.SBR     = BaudRate;   /* set Baud Rate */

  ESCI_A.LCR.B.LIN       = 1;                 /* enable LIN Mode */

  ESCI_A.CR1.B.TE        = 1;                /* Enable transmitter */

  ESCI_A.CR1.B.RE        = 1;                /* Enable receiver */

  ESCI_A.LCR.B.LRES    = 0;               /* Reset the internal transmitter controller using bit SCI_LCR[LRES] */

  ESCI_A.CR2.B.TXDMA = 1;               /* enable the transmit DMA feature */

  ESCI_A.CR2.B.RXDMA = 1;               /* enable the receive DMA feature */

}

/* LEN: the number of data bytes to be transmitted */

/* TxData: pointing to LIN Tx frame data bytes, not frame header bytes */

void LinTxFrame(unsigned char  ID,   unsigned char  LEN, unsigned char  *TxData)

{

  /* Assuming that CodeWarrior IDE support variable-length array */

  unsigned char  DMATxFrame[LEN+3];

   /* Write LIN TX frame header and control information */

  DMATxFrame[0] = ID;

  DMATxFrame[1] = LEN;

  DMATxFrame[2] = 0xD0;     /* For LIN TX frame, TD must be set to 1 */

  memcpy(&DMATxFrame[3], TxData, LEN);

  EDMA.TCD[18].SADDR = (uint32)DMATxFrame;

  EDMA.TCD[18].SMOD  = 0;

  EDMA.TCD[18].SSIZE = 0;

  EDMA.TCD[18].DMOD  = 0;

  EDMA.TCD[18].DSIZE = 0;

  EDMA.TCD[18].SOFF  = 1;

  EDMA.TCD[18].NBYTES= 1;

  EDMA.TCD[18].SLAST = -(LEN + 3);

  EDMA.TCD[18].DADDR = (uint32)&ESCI_A.LTR.R;

  EDMA.TCD[18].CITER = LEN + 3;

  EDMA.TCD[18].DOFF  = 0;

  EDMA.TCD[18].BITER = LEN + 3;

  EDMA.TCD[18].D_REQ = 1;

  EDMA.TCD[18].START = 0;

  EDMA.ERQRL.B.ERQ18 = 1;

}

/* LEN: the number of data bytes requested from the LIN slave */

/* RxData: pointing to LIN Rx frame data bytes transmitted by the LIN slave, not frame header bytes */

void LinRxFrame(unsigned char ID, unsigned char LEN, unsigned char *RxData)

{

  /* TO = (10·LEN + 45) x 1.4  (LEN is the number of data bytes in the frame) */

   unsigned short TimeOutUpper = (14 * LinRxDataLength + 63) / 256;

   unsigned short TimeOutLower = (14 * LinRxDataLength + 63) % 256;

  unsigned char DMATxHeader[4];

  /*** TX DMA channel is used to fetch the LIN RX frame header and control information ***/

  DMATxHeader[0] = ID;

  DMATxHeader[1] = LEN;

  DMATxHeader[2] = TimeOutUpper + 0xC0;      /* For LIN RX frame, TD must be set to 0 */

  DMATxHeader[3] = TimeOutLower;

  EDMA.TCD[18].SADDR = (uint32)DMATxHeader;

  EDMA.TCD[18].SMOD  = 0;

  EDMA.TCD[18].SSIZE = 0;

  EDMA.TCD[18].DMOD  = 0;

  EDMA.TCD[18].DSIZE = 0;

  EDMA.TCD[18].SOFF  = 1;

  EDMA.TCD[18].NBYTES= 1;

  EDMA.TCD[18].SLAST = -4;

  EDMA.TCD[18].DADDR = (uint32)&ESCI_A.LTR.R;

  EDMA.TCD[18].CITER = 4;

  EDMA.TCD[18].DOFF  = 0;

  EDMA.TCD[18].BITER = 4;

  EDMA.TCD[18].D_REQ = 1;

  EDMA.TCD[18].START = 0;

  EDMA.ERQRL.B.ERQ18 = 1;

  /*** RX DMA channel is used to transfer the received frame data into the memory ***/

  EDMA.TCD[19].SADDR = (uint32)&ESCI_B.LRR.R;

  EDMA.TCD[19].SMOD  = 0;

  EDMA.TCD[19].SSIZE = 0;

  EDMA.TCD[19].DMOD  = 0;

  EDMA.TCD[19].DSIZE = 0;

  EDMA.TCD[19].SOFF  = 0;

  EDMA.TCD[19].NBYTES = 1;

  EDMA.TCD[19].SLAST = 0;

  EDMA.TCD[19].DADDR = (uint32)RxData;

  EDMA.TCD[19].CITER = LEN;

  EDMA.TCD[19].DOFF  = 1;

  EDMA.TCD[19].DLAST_SGA = -LEN;

  EDMA.TCD[19].BITER = LEN;

  EDMA.TCD[19].D_REQ = 0;

  EDMA.TCD[19].START = 0;

  EDMA.ERQRL.B.ERQ19 = 1;

}

0 Kudos

975 Views
plabgh
Contributor I

Hi, Petr

Thank you for your answer.

I still have a question about writing SCI_LTR register.

The structure of SCI_LTR register, as describes in the document MPC563XMRM.pdf :

pastedImage_0.png

why should we write LIN frame header bytes separately into the most upper byte rather than their own fields in the SCI_LTR register ?

The most upper byte of the SCI_LTR register is DATA[24:31] field or is P+ID[0-7] field ???

And, when I want to transimit LIN data bytes,  how should i write the SCI_LTR register ?

First method:

ESCI_A.LTR.R = 0x11 << 24;   //1st data byte

......

ESCI_A.LTR.R = 0x88 << 24;   //8th data byte

Or, second method:

ESCI_A.LTR.R = 0x11;   //1st data byte

......

ESCI_A.LTR.R = 0x88;   //8th data byte

And, my device is TRK-MPC5634M (144 Pins).

I want to test LIN demo of dma method by jumper connecting LIN_A with LIN_B in TRK-MPC5634M.

(GND of LIN_A and LIN_B are linked together, and LIN of LIN_A and LIN_B are linked together.)

Simulation LIN bus to transmit and receive data:

LIN_A module transmits data bytes and LIN_B module receives data bytes.

Because MPC5634M eSCI module (LIN_A and LIN_B) can only be a Master node functionality, especially the following content of red part about LIN RX frames generation, I'm not sure whether this method can correctly test the Tx and Rx function of LIN Demo using DMA ?

26.5.6.4.1 Application controlled LIN RX frames generation in MPC563XMRM.pdf, described as follows:

The first byte written to the SCI_LTR contains the Identifier and Identifier Parity fields. The second byte written defines the number of data bytes requested from the LIN slave. The third write access defines the CRC and checksum checking. The TD bit has to be set to 0 to invoke the RX frame generation. The TO field defines the upper part of the timeout value. The fourth byte written defines the lower part of the timeout value.

After the fourth byte is written the generation of a LIN RX frame starts. Firstly, a break field is transmitted, then the synch field and the protected identifier field. After the transmission of the protected identifier, the eSCI module starts to receive the frame data transmitted by the LIN slave. When the module has received a complete byte field, the received data is transferred into the LIN receive register (SCI_LRR) and the receive data ready flag RXRDY in the SR register (SCI_SR) is set.

0 Kudos

975 Views
plabgh
Contributor I

Anybody know how to solve this problem ???

0 Kudos