Need help with UART on MPC5748

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

Need help with UART on MPC5748

Jump to solution
3,782 Views
shijiaguo
Contributor II

I'm trying to test out the UART periphral on MPC5748G, but I’m stuck at where I’m trying to write data into the BDRL data buffer, while the UART is configured as FIFO mode.

 

Here are my initialization code:

 

void UART_init()

{

    LINFlexD_0.LINCR1.B.SLEEP = 0;  /* Clear Sleep bit */

    LINFlexD_0.LINCR1.B.INIT = 1;   /* Enter INIT mode */

    LINFlexD_0.UARTCR.B.UART = 1;   /* Enable UART mode */

    LINFlexD_0.UARTCR.B.RFBM = 1;   /* Rx FIFO mode */

    LINFlexD_0.UARTCR.B.TFBM = 1;   /* Tx FIFO mode */

LINFlexD_0.LINCR1.B.INIT = 0;   /* Leave INIT mode */

}

 

Here’s the write function:

 

void UART_tranceive(void)

{

    LINFlexD_0.UARTCR.B.TxEn = 1;

LINFlexD_0.BDRL.B.DATA0 = (uint8_t)0x08;

}

 

Every time this is run: LINFlexD_0.BDRL.B.DATA0 = (uint8_t)0x08, there’s the critical exception generated.

 

Can anyone tell me if I’m doing something wrong?

 

Also does anyone happen to have some sample code of UART? If it’s with DMA that would be even better. Thank you so much!

 

-Shijia

Labels (1)
Tags (3)
0 Kudos
Reply
1 Solution
2,656 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

this is the problem (copied from RM):

pastedImage_0.png

You need to force the compiler to use "stb" instruction (store byte).

If you use this one:

LINFlexD_0.BDRL.B.DATA0 = (uint8_t)0x08;... it reads 32bit word, mask the data and then write 32bit word back. But this is not allowed. As you can see in the table above, only "store byte" or "store half-word" instruction is allowed. Read operation is not allowed too. So, you can use something like this:

*(unsigned char*)(((unsigned int)(&LINFlexD_0.BDRL.R))+3) = ...;

Take the address of BDRL register, add 3 to get address of the byte 0 and re-type the address to pointer to byte. Then the compiler will use stb instruction and it will work.

In this SW example you can find functions for UART (without FIFO):

Example MPC5748G PinToggleStationery GHS614

Regards,

Lukas

View solution in original post

10 Replies
742 Views
Anilpatil_SasvaAuto
Contributor III

I'm trying to test out the UART peripheral on MPC5748G, but I’m stuck at where I’m trying to read data from the LINFlexD_7.BDRM.B.DATA4 data buffer.

My requirement: Try to transmit and receive 9 bytes of hex values as shown below.
TxBuffer[9] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}

I am attempting to read all 9 bytes using the above Rx ISR, but I am only receiving the first byte repeatedly, which is 0x11.

Expected Output:
TxBuffer[9] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
RxBuffer[9] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
 
Actual Output:
TxBuffer[9] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
RxBuffer[9] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
 
Could you please suggest what the issue is in the RxISR routine?
 
Please provide the correct Uart7_Rx_Isr routine to read valid 9 bytes and Uart7_Tx_Isr and Transmit function as well.
 

Please review my Uart7_Rx_Isr code below:

void Uart7_Rx_Isr (void)
{
    unsigned char Channel = 7U;
    unsigned char Data;
 
    if (1 == LINFlexD_7.UARTSR.B.DRFRFE)
    {
        Data = LINFlexD_7.BDRM.B.DATA4;
 
        LINFlexD_7.UARTSR.R &= UART_DRFRFE;      /* Clear data reception flag W1C */
 
       /*Save received data*/
       if (BufferTxdisplay_index < UART_7_TX_MAX_LENGTH)   //0 <12
      {
           BufferTxdisplay[BufferTxdisplay_index] = Data;
 
           BufferTxdisplay_index++;
      }
 
     if( (BufferTxdisplay_index >= 9) )
     {
        BufferTxdisplay_index = 0;
     }
   }
}
0 Kudos
Reply
2,657 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

this is the problem (copied from RM):

pastedImage_0.png

You need to force the compiler to use "stb" instruction (store byte).

If you use this one:

LINFlexD_0.BDRL.B.DATA0 = (uint8_t)0x08;... it reads 32bit word, mask the data and then write 32bit word back. But this is not allowed. As you can see in the table above, only "store byte" or "store half-word" instruction is allowed. Read operation is not allowed too. So, you can use something like this:

*(unsigned char*)(((unsigned int)(&LINFlexD_0.BDRL.R))+3) = ...;

Take the address of BDRL register, add 3 to get address of the byte 0 and re-type the address to pointer to byte. Then the compiler will use stb instruction and it will work.

In this SW example you can find functions for UART (without FIFO):

Example MPC5748G PinToggleStationery GHS614

Regards,

Lukas

2,656 Views
shijiaguo
Contributor II

Hi Lukas lukaszadrapa

Thank you so much, it totally makes sense. I had a suspicion too, but didn't know how to address it.

One more quick question, once I configure it as FIFO mode, I'm no longer able to see the BDRL and BDRM register values on my debugger. Is that normal? It shows up like this:

pastedImage_1.png

-Shijia

0 Kudos
Reply
2,656 Views
shijiaguo
Contributor II

I guess ignore my first question, I think it's my debugger trying to read all bytes at the same time and there might be some bus error. 

0 Kudos
Reply
2,656 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

I did quick test on my board and it works. See attached example. I used LINFlex 2 to be able to use USB-to-serial interface.

By the way, you can't see the BDRL and BDRM registers in debugger for the same reason which I mentioned in my first post - read of BDRL in FIFO mode is not allowed ever,  in case of BDRM we can read only byte 4 or half-word 2. Debugger probably uses word access, so it results in bus error.

Regards,

Lukas

0 Kudos
Reply
2,656 Views
shijiaguo
Contributor II

Thank you so much lukaszadrapa‌. It's working. What I missed was I was probing on the wrong pin and didn't connect the pad.... 

0 Kudos
Reply
2,656 Views
shijiaguo
Contributor II

Also I'm kinda stuck again after I did some more development. 

So here's my code:

void peri_clock_gating (void)
{
/*
* IMPORTANT: This function is called before the RAM initialization for
* sections .data and .bss is done so it must NOT rely on any initial
* value of a global or local static variable.
*/
MC_ME.RUN_PC[0].R = 0x00000000; /* gate off clock for all RUN modes */
MC_ME.RUN_PC[1].R = 0x000000FE; /* config. peri clock for all RUN modes */
MC_ME.PCTL[50].B.RUN_CFG = 0x1; /* LIN_0: select peri. cfg. RUN_PC[1] */
}

0 Kudos
Reply
2,656 Views
shijiaguo
Contributor II

Sorry to be continued. 

void UART_init()
{
LINFlexD_0.LINCR1.B.INIT = 1; /* Enter Initialization Mode */
LINFlexD_0.LINCR1.B.SLEEP = 0; /* Exit Sleep Mode */
LINFlexD_0.UARTCR.B.UART = 1; /* UART Enable- Req'd before UART config.*/
LINFlexD_0.UARTCR.R = 0x0033; /* UART Ena, 1 byte tx, no parity, 8 data*/
LINFlexD_0.UARTSR.B.SZF = 1; /* CHANGE THIS LINE Clear the Zero status bit */
LINFlexD_0.UARTSR.B.DRFRFE = 1; /* CHANGE THIS LINE Clear DRFRFE flag - W1C */

LINFlexD_0.LINCR1.B.INIT = 0; /* Exit Initialization Mode */

SIUL2.MSCR[245].B.SSS = 1; /* Pad PP5: Source signal is LIN0_TX */
SIUL2.MSCR[245].B.OBE = 1; /* Pad PP5: OBE=1. */
SIUL2.MSCR[245].B.SRC = 3; /* Pad PP5: Full strength slew rate */

}

void UART_tranceive(void)
{
/while (LINFlexD_0.UARTSR.B.DTFTFF == 0) {;} /* Wait for data trans complete*/
LINFlexD_0.UARTSR.R &= 0x02; /* Clear DTFTFF flag - W1C */

LINFlexD_0.BDRL.B.DATA0 = 0x08;

}

0 Kudos
Reply
2,656 Views
shijiaguo
Contributor II

Sorry I don't know why everytime I hit ctrl-s it just post it...

Continue...

My UART_tranceive() is called periodically (every 1 ms). So here since I connected LIN0_Tx with Pad PP5, I should see UART Tx signals on PP5, right? However, I'm not seeing anything on PP5. I can see that the UARTSR_DTFTFF is toggling between 0 and 1. I'm using MPC5748G EVB board: http://www.nxp.com/files/microcontrollers/doc/user_guide/MPC5748GEVBUG.pdf?fasp=1&WT_TYPE=Users%20Gu... 

 

Am I missing something? Any help is appreciated. Thank you!

lukaszadrapa‌  

0 Kudos
Reply
2,656 Views
alexvinchev
Contributor V